4 people like it.
Like the snippet!
Church numerals
Church numerals via rank-2 polymorphism
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
|
type Church =
abstract Apply<'T> : ('T -> 'T) * 'T -> 'T
let zero =
{
new Church with
member self.Apply(f, x) = x
}
let succ (nat : Church) =
{
new Church with
member self.Apply(f, x) = f <| nat.Apply(f, x)
}
let one = succ zero
let two = succ one
let (<+>) (first : Church) (second : Church) =
first.Apply(succ, second)
let (<*>) (first : Church) (second : Church) =
first.Apply((<+>) second, zero)
let (<^>) (first : Church) (second : Church) =
second.Apply((<*>) first, one)
let toInt (nat : Church) =
nat.Apply((+)1, 0)
let three = two <+> one
let six = three <*> two
let eight = two <^> three
three |> toInt // 3
six |> toInt // 6
eight |> toInt // 8
|
abstract member Church.Apply : ('T -> 'T) * 'T -> 'T
Full name: Script.Church.Apply
val zero : Church
Full name: Script.zero
type Church =
interface
abstract member Apply : ('T -> 'T) * 'T -> 'T
end
Full name: Script.Church
val self : Church
abstract member Church.Apply : ('T -> 'T) * 'T -> 'T
val f : ('a -> 'a)
val x : 'a
val succ : nat:Church -> Church
Full name: Script.succ
val nat : Church
val one : Church
Full name: Script.one
val two : Church
Full name: Script.two
val first : Church
val second : Church
val toInt : nat:Church -> int
Full name: Script.toInt
val three : Church
Full name: Script.three
val six : Church
Full name: Script.six
val eight : Church
Full name: Script.eight
More information