currying . , . (Swift .)
: " - , ". . .
typealias Church = (_ f: ((Int) -> Int), _ x: Int) -> Int
, , .
N :
func numToChurch(_ n: Int) -> Church {
guard n > 0 else { return { (_, n) in n } }
return { (f, x) in
numToChurch(n - 1)(f, f(x))
}
}
- :
func churchToNum(_ church: Church) -> Int {
return church({$0 + 1}, 0)
}
, ( , , @kennytm ). Currying Swift:
typealias Church = (@escaping (Int) -> Int) -> (Int) -> Int
func numToChurch(_ n: Int) -> Church {
// Church(0) does not apply the function
guard n > 0 else { return { _ in { n in n } } }
return { f in { x in
numToChurch(n - 1)(f)(f(x))
}
}
}
func churchToNum(_ church: Church) -> Int {
return church({$0 + 1})(0)
}
: " @escaping , ?" , , ( ), @escaping.
.
, ? . . , ?
func zero() -> Church
? f
func zero() -> Church {
return { f in { x in
x
} }
}
:
func one() -> Church {
return { f in { x in
f(x)
} }
}
func two() -> Church {
return { f in { x in
f(f(x))
} }
}
succ? :
func succ(_ n: @escaping Church) -> Church {
Swift, , @escaping _, . (Swift , -. , .) ? f n:
func succ(_ n: @escaping Church) -> Church {
return { f in { x in
let nValue = n(f)(x)
return f(nValue)
} }
}
, sum? , , , , , .
func sum(_ n: @escaping Church) -> (@escaping Church) -> Church
, , Swift. (, , , .)
func sum(_ n: @escaping Church) -> (@escaping Church) -> Church {
return { m in { f in { x in
let nValue = n(f)(x)
return m(f)(nValue)
} } }
}
- Church typealias. ", --", . " " , . , , Int Int. , , .
, FP, , Swift ( ).
-, ... . . , , . , , { f in { x in ...} }, . . , stdlib
infix operator β : CompositionPrecedence
precedencegroup CompositionPrecedence {
associativity: left
higherThan: TernaryPrecedence
}
public func β<T, U, V>(g: @escaping (U) -> V, f: @escaping (T) -> U) -> ((T) -> V) {
return { g(f($0)) }
}
, ?
func numToChurch(_ n: Int) -> Church {
guard n > 0 else { return zero() }
return { f in f β numToChurch(n - 1)(f) }
}
func succ(_ n: @escaping Church) -> Church {
return { f in f β n(f) }
}
func sum(_ n: @escaping Church) -> (@escaping Church) -> Church {
return { m in { f in
n(f) β m(f)
} }
}
x. , . .
, , , . Swift , . , zero(). . , ? .
struct Church {
typealias F = (@escaping (Int) -> Int) -> (Int) -> Int
let applying: F
static let zero: Church = Church{ _ in { $0 } }
func successor() -> Church {
return Church{ f in f β self.applying(f) }
}
static func + (lhs: Church, rhs: Church) -> Church {
return Church{ f in lhs.applying(f) β rhs.applying(f) }
}
}
extension Church {
init(_ n: Int) {
if n <= 0 { self = .zero }
else { applying = { f in f β Church(n - 1).applying(f) } }
}
}
extension Int {
init(_ church: Church) {
self = church.applying{ $0 + 1 }(0)
}
}
Int(Church(3) + Church(7).successor() + Church.zero)