001/* 002 * Copyright (c) 2012-2018 Institut National des Sciences Appliquées de Lyon (INSA Lyon) and others 003 * 004 * This program and the accompanying materials are made available under the 005 * terms of the Eclipse Public License 2.0 which is available at 006 * http://www.eclipse.org/legal/epl-2.0. 007 * 008 * SPDX-License-Identifier: EPL-2.0 009 */ 010 011package gololang; 012 013/** 014 * Structure having a head and a tail. 015 * <p> 016 * This interface can be used to define any recursive sequence of object, 017 * such as lists or generators. It is well suited to recursive algorithms, and 018 * thus can be seen as an alternative to the {@code Iterable} interface. 019 * <p> 020 * For example, one can compute the size of such an object with: 021 * <pre class="listing"><code class="lang-java" data-lang="java"> 022 * static int size(HeadTail<?> o) { 023 * if (o.isEmpty()) { return 0; } 024 * return 1 + size(o.tail()); 025 * } 026 * </code></pre> 027 * or in Golo: 028 * <pre class="listing"><code class="lang-golo" data-lang="golo"> 029 * function size = |ht| -> match { 030 * when ht: isEmpty() then 0 031 * otherwhise 1 + size(ht: tail()) 032 * } 033 * </code></pre> 034 * <p> 035 * Note that the {@code size} method is not provided since this interface 036 * can be implemented by infinite generators. 037 * <p> 038 * A {@code List} augmentation is provided, as well as corresponding special 039 * methods on arrays ({@code Object[]}/{@code array[]}) 040 * 041 * @param <E> the type of the elements held in this structure. 042 */ 043public interface HeadTail<E> extends Iterable<E> { 044 045 /** 046 * Get the head of the structure. 047 * 048 * @return the first element of the structure, or {@code null} if the structure is empty. 049 */ 050 E head(); 051 052 /** 053 * Get the tail of the structure. 054 * <p> 055 * To be side effect free, this method should return a deep copy of the original structure or an 056 * immutable view on it. 057 * 058 * @return a new {@code HeadTail} containing all the elements but the first, or a empty one 059 * if no elements remains. 060 */ 061 HeadTail<E> tail(); 062 063 /** 064 * Checks if the structure is empty or not. 065 * 066 * @return {@code true} if the structure contains no element, {@code false} otherwise. 067 */ 068 boolean isEmpty(); 069 070 /** 071 * Util method to wrap a {@code HeadTail} instance into an {@code Iterable} 072 * 073 * @param headTail the instance to wrap 074 * @return an iterable on the values contained in the wrapped instance 075 */ 076 static <E> Iterable<E> toIterable(HeadTail<E> headTail) { 077 return () -> new HeadTailIterator<>(headTail); 078 } 079 080}