Avatar
@swift-4.1.3 import Foundation public protocol MapType { associatedtype Domain associatedtype Codomain init(_ fnc: @escaping (Domain) -> Codomain) func applied(to x: Domain) -> Codomain } public struct Map<Domain, Codomain>: MapType { internal let fnc: (Domain) -> Codomain public init(_ fnc: @escaping (Domain) -> Codomain) { self.fnc = fnc } public func applied(to x: Domain) -> Codomain { return fnc(x) } } public protocol EndType: MapType where Domain == Codomain { 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 { return Self { x in // ココで EXC_BAD_ACCESS self.applied(to: g.applied(to: x)) } } } extension Map: EndType where Domain == Codomain { public static var identity: Map<Domain, Codomain> { return Map { x in x } } public func composed(with g: Map<Domain, Codomain>) -> Map<Domain, Codomain> { print("Map.composed self: \(type(of: self))") return Map { x in exit(0) // return self.applied(to: g.applied(to: x)) } } } public extension Array where Element: EndType { func composed() -> Element { return self.reduce(Element.identity) { res, f in print("Array.composed res: \(type(of: res))") return res.composed(with: f) } } } let f = Map<Int, Int> { x in 2 * x } let g = [f, f].composed() print(g.applied(to: 0))