Avatar
@swiftbot import Foundation public protocol EndType where DomainType == CodomainType { associatedtype DomainType associatedtype CodomainType init(_ fnc: @escaping (DomainType) -> CodomainType) func applied(to x: DomainType) -> CodomainType static var identity: Self { get } func composed(with f: Self) -> Self } public extension EndType { public static var identity: Self { return Self { x in x } } public func composed(with g: Self) -> Self { let fnc: (DomainType) -> DomainType = { x1 in let x2: DomainType = g.applied(to: x1) let x3: DomainType = self.applied(to: x2) return x3 } return Self.init(fnc) } } public struct Map<Domain>: EndType { internal let fnc: (Domain) -> Domain public init(_ fnc: @escaping (Domain) -> Domain) { self.fnc = fnc } public func applied(to x: Domain) -> Domain { return fnc(x) } } public extension Array where Element: EndType { func composed() -> Element { return self.reduce(Element.identity) { (res, f) in res.composed(with: f) } } } let f: Map<Int> = Map { x in 2 * x } let fs: Array<Map<Int>> = [f, f, f] let g: Map<Int> = fs.composed() let t: Int = g.applied(to: 1) print(t)