4 people like it.

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
Raw view Test code New version

More information

Link:http://fssnip.net/gm
Posted:11 years ago
Author:Nick Palladinos
Tags: rank-2 polymorphism , church numerals