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}