<commit_before>//
//  Arrow.swift
//  Basis
//
//  Created by <NAME> on 9/9/14.
//  Copyright (c) 2014 TypeLift. All rights reserved.
//  Released under the MIT license.
//

/// An Arrow is most famous for being a "Generalization of a Monad".  They're probably better
/// described as a more general view of computation.  Where a monad M<A> yields a value of type A
/// given some context, an Arrow A<B, C> is a function from B -> C in some context A.  Functions are
/// the simplest kind of Arrow (pun intended).  Their context parameter, A, is essentially empty.
/// From there, the B -> C part of the arrow gets alpha-reduced to the A -> B part of the function
/// type.
///
/// Arrows can be modelled with circuit-esque diagrams, and indeed that can often be a better way to
/// envision the various arrow operators.
///
/// - >>>       a -> [ f ] -> b -> [ g ] -> c
/// - <<<       a -> [ g ] -> b -> [ f ] -> c
///
/// - arr       a -> [ f ] -> b
///
/// - first     a -> [ f ]  -> b
///             c - - - - - -> c
///
/// - second    c - - - - - -> c
///             a -> [ f ]  -> b
///
///
/// - ***       a - [ f ] -> b - •
///                               \
///                                o - -> (b, d)
///                               /
///             c - [ g ] -> d - •
///
///
///                 • - [ f ] -> b - •
///                 |                 \
/// - &&&       a - o                  o - -> (b, c)
///                 |                 /
///                 • - [ g ] -> c - •
///
/// Arrows inherit from Category so we can get Composition For Free™.
public protocol Arrow : Category {
	/// Some arbitrary target our arrow can compose with.
	typealias D
	/// Some arbitrary target our arrow can compose with.
	typealias E
	
	/// Type of the result of first().
	typealias FIRST = K2<(A, D), (B, D)>
	/// Type of the result of second().
	typealias SECOND = K2<(D, A), (D, B)>
	
	/// Some arrow with an arbitrary target and source.  Used in split().
	typealias ADE = K2<D, E>
	/// Type of the result of ***.
	typealias SPLIT = K2<(A, D), (B, E)>
	
	/// Some arrow from our target to some other arbitrary target.  Used in fanout().
	typealias ABD = K2<A, D>
	
	/// Type of the result of &&&.
	typealias FANOUT = K2<B, (B, D)>
	
	/// Lift a function to an arrow.
	class func arr(A -> B) -> Self
	
	/// Splits the arrow into two tuples that model a computation that applies our Arrow to an
	/// argument on the "left side" and sends the "right side" through unchanged.
	///
	/// The mirror image of second().
	func first() -> FIRST
	
	/// Splits the arrow into two tuples that model a computation that applies our Arrow to an
	/// argument on the "right side" and sends the "left side" through unchanged.
	///
	/// The mirror image of first().
	func second() -> SECOND
	
	/// Split | Splits two computations and combines the result into one Arrow yielding a tuple of
	/// the result of each side.
	func ***(Self, ADE) -> SPLIT
	
	/// Fanout | Given two functions with the same source but different targets, this function
	/// splits the computation and combines the result of each Arrow into a tuple of the result of
	/// each side.
	func &&&(Self, ABD) -> FANOUT
}

/// Arrows that can produce an identity arrow.
public protocol ArrowZero : Arrow {
	/// An arrow from A -> B.  Colloquially, the "zero arrow".
	typealias ABC = K2<A, B>

	/// The identity arrow.
	class func zeroArrow() -> ABC
}

/// A monoid for Arrows.
public protocol ArrowPlus : ArrowZero {
	/// A binary function that combines two arrows.
	func <+>(ABC, ABC) -> ABC
}

/// Arrows that permit "choice" or selecting which side of the input to apply themselves to.
///
/// - left                     a - - [f] - - > b
///                            |
///             a - [f] -> b - o-----EITHER-----
///                            |
///                            d - - - - - - > d
///
/// - right                    d - - [f] - - > d
///                            |
///             a - [f] -> b - o-----EITHER-----
///                            |
///                            a - - - - - - > b
///
/// - +++       a - [ f ] -> b - •        • a - [ f ] -> b
///                               \       |
///                                o - -> o-----EITHER-----
///                               /       |
///             d - [ g ] -> e - •        • d - [ g ] -> e
///
/// - |||       a - [ f ] -> c - •        • a - [ f ] -> c •
///                               \       |                 \
///                                o - -> o-----EITHER-------o - -> c
///                               /       |                 /
///             b - [ g ] -> c - •        • b - [ g ] -> c •
///
public protocol ArrowChoice : Arrow {
	/// The result of left
	typealias LEFT = K2<Either<A, D>, Either<B, D>>
	/// The result of right
	typealias RIGHT = K2<Either<D, A>, Either<D, B>>

	/// The result of +++
	typealias SPLAT = K2<Either<A, D>, Either<B, E>>

	/// Some arrow from a different source and target for fanin.
	typealias ACD = K2<B, D>
	/// The result of |||
	typealias FANIN = K2<Either<A, B>, D>

	/// Feed marked inputs through the argument arrow, passing the rest through unchanged to the <commit_msg>Flip apply in right diagram<commit_after>//
//  Arrow.swift
//  Basis
//
//  Created by <NAME> on 9/9/14.
//  Copyright (c) 2014 TypeLift. All rights reserved.
//  Released under the MIT license.
//

/// An Arrow is most famous for being a "Generalization of a Monad".  They're probably better
/// described as a more general view of computation.  Where a monad M<A> yields a value of type A
/// given some context, an Arrow A<B, C> is a function from B -> C in some context A.  Functions are
/// the simplest kind of Arrow (pun intended).  Their context parameter, A, is essentially empty.
/// From there, the B -> C part of the arrow gets alpha-reduced to the A -> B part of the function
/// type.
///
/// Arrows can be modelled with circuit-esque diagrams, and indeed that can often be a better way to
/// envision the various arrow operators.
///
/// - >>>       a -> [ f ] -> b -> [ g ] -> c
/// - <<<       a -> [ g ] -> b -> [ f ] -> c
///
/// - arr       a -> [ f ] -> b
///
/// - first     a -> [ f ]  -> b
///             c - - - - - -> c
///
/// - second    c - - - - - -> c
///             a -> [ f ]  -> b
///
///
/// - ***       a - [ f ] -> b - •
///                               \
///                                o - -> (b, d)
///                               /
///             c - [ g ] -> d - •
///
///
///                 • - [ f ] -> b - •
///                 |                 \
/// - &&&       a - o                  o - -> (b, c)
///                 |                 /
///                 • - [ g ] -> c - •
///
/// Arrows inherit from Category so we can get Composition For Free™.
public protocol Arrow : Category {
	/// Some arbitrary target our arrow can compose with.
	typealias D
	/// Some arbitrary target our arrow can compose with.
	typealias E
	
	/// Type of the result of first().
	typealias FIRST = K2<(A, D), (B, D)>
	/// Type of the result of second().
	typealias SECOND = K2<(D, A), (D, B)>
	
	/// Some arrow with an arbitrary target and source.  Used in split().
	typealias ADE = K2<D, E>
	/// Type of the result of ***.
	typealias SPLIT = K2<(A, D), (B, E)>
	
	/// Some arrow from our target to some other arbitrary target.  Used in fanout().
	typealias ABD = K2<A, D>
	
	/// Type of the result of &&&.
	typealias FANOUT = K2<B, (B, D)>
	
	/// Lift a function to an arrow.
	class func arr(A -> B) -> Self
	
	/// Splits the arrow into two tuples that model a computation that applies our Arrow to an
	/// argument on the "left side" and sends the "right side" through unchanged.
	///
	/// The mirror image of second().
	func first() -> FIRST
	
	/// Splits the arrow into two tuples that model a computation that applies our Arrow to an
	/// argument on the "right side" and sends the "left side" through unchanged.
	///
	/// The mirror image of first().
	func second() -> SECOND
	
	/// Split | Splits two computations and combines the result into one Arrow yielding a tuple of
	/// the result of each side.
	func ***(Self, ADE) -> SPLIT
	
	/// Fanout | Given two functions with the same source but different targets, this function
	/// splits the computation and combines the result of each Arrow into a tuple of the result of
	/// each side.
	func &&&(Self, ABD) -> FANOUT
}

/// Arrows that can produce an identity arrow.
public protocol ArrowZero : Arrow {
	/// An arrow from A -> B.  Colloquially, the "zero arrow".
	typealias ABC = K2<A, B>

	/// The identity arrow.
	class func zeroArrow() -> ABC
}

/// A monoid for Arrows.
public protocol ArrowPlus : ArrowZero {
	/// A binary function that combines two arrows.
	func <+>(ABC, ABC) -> ABC
}

/// Arrows that permit "choice" or selecting which side of the input to apply themselves to.
///
/// - left                     a - - [ f ] - - > b
///                            |
///             a - [f] -> b - o------EITHER------
///                            |
///                            d - - - - - - - > d
///
/// - right                    d - - - - - - - > d
///                            |
///             a - [f] -> b - o-----EITHER-----
///                            |
///                            a - - [ f ] - - > b
///
/// - +++       a - [ f ] -> b - •        • a - [ f ] -> b
///                               \       |
///                                o - -> o-----EITHER-----
///                               /       |
///             d - [ g ] -> e - •        • d - [ g ] -> e
///
/// - |||       a - [ f ] -> c - •        • a - [ f ] -> c •
///                               \       |                 \
///                                o - -> o-----EITHER-------o - -> c
///                               /       |                 /
///             b - [ g ] -> c - •        • b - [ g ] -> c •
///
public protocol ArrowChoice : Arrow {
	/// The result of left
	typealias LEFT = K2<Either<A, D>, Either<B, D>>
	/// The result of right
	typealias RIGHT = K2<Either<D, A>, Either<D, B>>

	/// The result of +++
	typealias SPLAT = K2<Either<A, D>, Either<B, E>>

	/// Some arrow from a different source and target for fanin.
	typealias ACD = K2<B, D>
	/// The result of |||
	typealias FANIN = K2<Either<A, B>, D>

	/// Feed marked inputs through the argument arrow, passing the rest through unchanged to the 
{'fraction_non_alphanumeric': 0.16344127227438207, 'fraction_numerical': 0.003832151753209427, 'mean_word_length': 1.2121212121212122, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 157, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 38, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3169958', 'n_tokens_mistral': 3221, 'n_tokens_neox': 3046, 'n_words': 1256}