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