我是函数式编程和 F# 的初学者。作为一个练习,我试图实现教堂数字。
首先,我将数字编码为:
let ZERO = fun p x -> x
let ONE = fun p x -> p x
let TWO = fun p x -> p(p x)
let THREE = fun p x -> p(p(p x))
let FIVE = fun p x ->p(p(p(p(p x))))
... etc
然后我编写了辅助函数来查看我的数字是否有效:
let toInt p = p (fun x->x+1) 0
例如:
toInt (THREE) |> printfn "%A"
正如预期的那样打印 3。
我还实现了一些算术函数:
let INC = fun n f x -> f((n(f))(x)) //incrementation
let DEC = fun n f x -> n (fun g -> fun h -> h(g f))(fun y->x)(fun y-> y) //decrementation
let ADD = fun m n -> n(INC)(m) //addition
let MUL = fun m n s z -> n(m s) z //multiplication
let POW = fun m n -> n(MUL m)ONE //exponential
所有这些似乎都工作正常:
toInt (INC THREE) |> printfn "%A" //prints 4
toInt (DEC THREE) |> printfn "%A" //prints 2
toInt (ADD THREE FIVE) |> printfn "%A" //prints 8
toInt (MUL THREE FIVE) |> printfn "%A" //prints 15
toInt (POW THREE FIVE) |> printfn "%A" //prints 243
但我真的很难实现减法:
let SUB = fun m n -> n(DEC m)
toInt (SUB FIVE THREE) |> printfn "%A" //gives 64
上面的方法看起来像某种指数而不是减法。
我也试过(正如维基建议的那样):
let SUB = fun m n -> n(DEC)m
但是当我尝试使用它时会导致类型不匹配:
toInt (SUB FIVE THREE) |> printfn "%A"
"Type mismatch. Expecting a
'(((('a -> 'b) -> ('b -> 'c) -> 'c) -> ('d -> 'e) -> ('f -> 'f) -> 'g) -> 'a -> 'e -> 'g) -> (('h -> 'h) -> 'h -> 'h) -> (int -> int) -> int -> 'i'
but given a
'(((('a -> 'b) -> ('b -> 'c) -> 'c) -> ('d -> 'e) -> ('f -> 'f) -> 'g) -> (('a -> 'b) -> ('b -> 'c) -> 'c) -> ('d -> 'e) -> ('f -> 'f) -> 'g) -> ((('a -> 'b) -> ('b -> 'c) -> 'c) -> ('d -> 'e) -> ('f -> 'f) -> 'g) -> (('a -> 'b) -> ('b -> 'c) -> 'c) -> ('d -> 'e) -> ('f -> 'f) -> 'g'
The types ''a' and '('a -> 'b) -> ('b -> 'c) -> 'c' cannot be unified"
我被卡住了,我做错了什么?我也很感激任何关于如何改进我的代码的建议。