All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.staccatocommons.collections.stream.Transformable Maven / Gradle / Ivy

/*
 Copyright (c) 2011, The Staccato-Commons Team

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation; version 3 of the License.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Lesser General Public License for more details.
 */
package net.sf.staccatocommons.collections.stream;

import net.sf.staccatocommons.collections.restrictions.Projection;
import net.sf.staccatocommons.defs.Applicable;
import net.sf.staccatocommons.defs.Applicable2;
import net.sf.staccatocommons.defs.Thunk;
import net.sf.staccatocommons.restrictions.check.NonNull;

/**
 * Stream interface for transforming it into a new one supplying a
 * transformation function.
 * 
 * @author flbulgarelli
 * 
 */
public interface Transformable {

  /**
   * Lazily applies the given function to this {@link Stream}.
   * 
   * @param 
   * @param function
   *          the function to apply to this stream
   * @return a new stream that will retrieve elements from the result of
   *         applying the given function to this stream
   */
  @Projection
   Stream transform(@NonNull Applicable, ? extends Stream> function);

  /**
   * Lazily applies the given function to this stream,
   * deconstructing this stream into head and tail, or into an empty stream.
   * 
   * Unlike {@link Stream#transform(Applicable)}, whose function will receive
   * the whole stream, the given {@link DeconsApplicable}, when applied, will
   * take the head and tail of this {@link Stream}, if non empty, or no
   * arguments, if the stream is empty.
   * 
   * @param 
   * @param function
   * @return a new stream that will retrieve elements from the result of
   *         applying the given function to this stream
   * @see #decons()
   */
  @Projection
   Stream transform(@NonNull DeconsApplicable function);

  /**
   * Lazily applies the given function to this stream,
   * deconstructing this stream into a head thunk and tail, or into an empty
   * stream.
   * 
   * Unlike {@link Stream#transform(Applicable)}, whose function will receive
   * the whole stream, the given {@link DeconsApplicable}, when applied, will
   * take a head's thunk and tail of this {@link Stream}, if non empty, or no
   * arguments, if the stream is empty.
   * 
   * @param 
   * @param function
   * @return a new stream that will retrieve elements from the result of
   *         applying the given function to this stream
   * @see #delayedDecons()
   */
  @Projection
   Stream transform(@NonNull DelayedDeconsApplicable function);

  /**
   * @author flbulgarelli
   * @param 
   */
  public interface EmptyApplicable {
    /**
     * Applies this transformation when this Stream can not be deconstructed in
     * head and tail, because it is empty.
     * 
     * @return the result of applying this transformation over and empty
     *         {@link Stream}
     */
    A emptyApply();
  }

  /**
   * An {@link Applicable2} that can transform a {@link Stream} by
   * deconstructing it into head and tail, or into an empty stream.
   * 
   * @author flbulgarelli
   * 
   * @param 
   *          input stream type
   * @param 
   *          output stream type
   */
  public interface DeconsApplicable extends Applicable2, Stream>,
    EmptyApplicable> {

    /**
     * Applies this transformation to a non empty Stream splitted into tail and
     * head.
     * 
     * Independently of the original stream source, the tail Stream is always
     * non-repeatable.
     * 
     * {@link Stream}s will send this message when evaluating
     * {@link Stream#transform(DeconsApplicable)}
     */
    Stream apply(A head, Stream tail);
  }

  /**
   * An {@link Applicable2} that can transform a {@link Stream} by
   * deconstructing it into head thunk and tail, or into an empty stream.
   * 
   * @author flbulgarelli
   * 
   * @param 
   *          input stream type
   * @param 
   *          output stream type
   */
  public interface DelayedDeconsApplicable extends
    Applicable2, Stream, Stream>, EmptyApplicable> {

    /**
     * Applies this transformation to a non empty Stream splitted into tail and
     * head's thunk.
     * 
     * Independently of the original stream source, the tail Stream is always
     * non-repeatable.
     * 
     * {@link Stream}s will send this message when evaluating
     * {@link Stream#transform(DeconsApplicable)}
     */
    Stream apply(Thunk head, Stream tail);

  }
}