| // |
| // RACSequence.h |
| // ReactiveCocoa |
| // |
| // Created by Justin Spahr-Summers on 2012-10-29. |
| // Copyright (c) 2012 GitHub. All rights reserved. |
| // |
| |
| #import <Foundation/Foundation.h> |
| #import "RACStream.h" |
| |
| @class RACScheduler; |
| @class RACSignal; |
| |
| /// Represents an immutable sequence of values. Unless otherwise specified, the |
| /// sequences' values are evaluated lazily on demand. Like Cocoa collections, |
| /// sequences cannot contain nil. |
| /// |
| /// Most inherited RACStream methods that accept a block will execute the block |
| /// _at most_ once for each value that is evaluated in the returned sequence. |
| /// Side effects are subject to the behavior described in |
| /// +sequenceWithHeadBlock:tailBlock:. |
| /// |
| /// Implemented as a class cluster. A minimal implementation for a subclass |
| /// consists simply of -head and -tail. |
| @interface RACSequence : RACStream <NSCoding, NSCopying, NSFastEnumeration> |
| |
| /// The first object in the sequence, or nil if the sequence is empty. |
| /// |
| /// Subclasses must provide an implementation of this method. |
| @property (nonatomic, strong, readonly) id head; |
| |
| /// All but the first object in the sequence, or nil if the sequence is empty. |
| /// |
| /// Subclasses must provide an implementation of this method. |
| @property (nonatomic, strong, readonly) RACSequence *tail; |
| |
| /// Evaluates the full sequence to produce an equivalently-sized array. |
| @property (nonatomic, copy, readonly) NSArray *array; |
| |
| /// Returns an enumerator of all objects in the sequence. |
| @property (nonatomic, copy, readonly) NSEnumerator *objectEnumerator; |
| |
| /// Converts a sequence into an eager sequence. |
| /// |
| /// An eager sequence fully evaluates all of its values immediately. Sequences |
| /// derived from an eager sequence will also be eager. |
| /// |
| /// Returns a new eager sequence, or the receiver if the sequence is already |
| /// eager. |
| @property (nonatomic, copy, readonly) RACSequence *eagerSequence; |
| |
| /// Converts a sequence into a lazy sequence. |
| /// |
| /// A lazy sequence evaluates its values on demand, as they are accessed. |
| /// Sequences derived from a lazy sequence will also be lazy. |
| /// |
| /// Returns a new lazy sequence, or the receiver if the sequence is already lazy. |
| @property (nonatomic, copy, readonly) RACSequence *lazySequence; |
| |
| /// Invokes -signalWithScheduler: with a new RACScheduler. |
| - (RACSignal *)signal; |
| |
| /// Evaluates the full sequence on the given scheduler. |
| /// |
| /// Each item is evaluated in its own scheduled block, such that control of the |
| /// scheduler is yielded between each value. |
| /// |
| /// Returns a signal which sends the receiver's values on the given scheduler as |
| /// they're evaluated. |
| - (RACSignal *)signalWithScheduler:(RACScheduler *)scheduler; |
| |
| /// Applies a left fold to the sequence. |
| /// |
| /// This is the same as iterating the sequence along with a provided start value. |
| /// This uses a constant amount of memory. A left fold is left-associative so in |
| /// the sequence [1,2,3] the block would applied in the following order: |
| /// reduce(reduce(reduce(start, 1), 2), 3) |
| /// |
| /// start - The starting value for the fold. Used as `accumulator` for the |
| /// first fold. |
| /// reduce - The block used to combine the accumulated value and the next value. |
| /// Cannot be nil. |
| /// |
| /// Returns a reduced value. |
| - (id)foldLeftWithStart:(id)start reduce:(id (^)(id accumulator, id value))reduce; |
| |
| /// Applies a right fold to the sequence. |
| /// |
| /// A right fold is equivalent to recursion on the list. The block is evaluated |
| /// from the right to the left in list. It is right associative so it's applied |
| /// to the rightmost elements first. For example, in the sequence [1,2,3] the |
| /// block is applied in the order: |
| /// reduce(1, reduce(2, reduce(3, start))) |
| /// |
| /// start - The starting value for the fold. |
| /// reduce - The block used to combine the accumulated value and the next head. |
| /// The block is given the accumulated value and the value of the rest |
| /// of the computation (result of the recursion). This is computed when |
| /// you retrieve its value using `rest.head`. This allows you to |
| /// prevent unnecessary computation by not accessing `rest.head` if you |
| /// don't need to. |
| /// |
| /// Returns a reduced value. |
| - (id)foldRightWithStart:(id)start reduce:(id (^)(id first, RACSequence *rest))reduce; |
| |
| /// Check if any value in sequence passes the block. |
| /// |
| /// block - The block predicate used to check each item. Cannot be nil. |
| /// |
| /// Returns a boolean indiciating if any value in the sequence passed. |
| - (BOOL)any:(BOOL (^)(id value))block; |
| |
| /// Check if all values in the sequence pass the block. |
| /// |
| /// block - The block predicate used to check each item. Cannot be nil. |
| /// |
| /// Returns a boolean indicating if all values in the sequence passed. |
| - (BOOL)all:(BOOL (^)(id value))block; |
| |
| /// Returns the first object that passes the block. |
| /// |
| /// block - The block predicate used to check each item. Cannot be nil. |
| /// |
| /// Returns an object that passes the block or nil if no objects passed. |
| - (id)objectPassingTest:(BOOL (^)(id value))block; |
| |
| /// Creates a sequence that dynamically generates its values. |
| /// |
| /// headBlock - Invoked the first time -head is accessed. |
| /// tailBlock - Invoked the first time -tail is accessed. |
| /// |
| /// The results from each block are memoized, so each block will be invoked at |
| /// most once, no matter how many times the head and tail properties of the |
| /// sequence are accessed. |
| /// |
| /// Any side effects in `headBlock` or `tailBlock` should be thread-safe, since |
| /// the sequence may be evaluated at any time from any thread. Not only that, but |
| /// -tail may be accessed before -head, or both may be accessed simultaneously. |
| /// As noted above, side effects will only be triggered the _first_ time -head or |
| /// -tail is invoked. |
| /// |
| /// Returns a sequence that lazily invokes the given blocks to provide head and |
| /// tail. `headBlock` must not be nil. |
| + (RACSequence *)sequenceWithHeadBlock:(id (^)(void))headBlock tailBlock:(RACSequence *(^)(void))tailBlock; |
| |
| @end |
| |
| @interface RACSequence (Deprecated) |
| |
| - (id)foldLeftWithStart:(id)start combine:(id (^)(id accumulator, id value))combine __attribute__((deprecated("Renamed to -foldLeftWithStart:reduce:"))); |
| - (id)foldRightWithStart:(id)start combine:(id (^)(id first, RACSequence *rest))combine __attribute__((deprecated("Renamed to -foldRightWithStart:reduce:"))); |
| |
| @end |