RosettaCodeData/Task/Church-numerals/Phix/church-numerals.phix
2026-02-01 16:33:20 -08:00

86 lines
2 KiB
Text

with javascript_semantics
type church(object c)
-- eg {r_add,1,{a,b}}
return sequence(c) and length(c)=3
and integer(c[1]) and integer(c[2])
and sequence(c[3]) and length(c[3])=2
end type
function succ(church c)
-- eg {add,1,{a,b}} => {add,2,{a,b}} aka a+b => a+b+b
c = deep_copy(c)
c[2] += 1
return c
end function
-- three normal integer-handling routines...
function add(integer n, a, b)
for i=1 to n do
a += b
end for
return a
end function
function mul(integer n, a, b)
for i=1 to n do
a *= b
end for
return a
end function
function pow(integer n, a, b)
for i=1 to n do
a = power(a,b)
end for
return a
end function
-- ...and three church constructors to match
-- (no maths here, just pure static data)
function addch(church c, d)
church res = {add,1,{c,d}}
return res
end function
function mulch(church c, d)
church res = {mul,1,{c,d}}
return res
end function
function powch(church c, d)
church res = {pow,1,{c,d}}
return res
end function
function tointch(church c)
-- note this is where the bulk of any processing happens
{integer rid, integer n, object x} = c
x = deep_copy(x)
for i=1 to length(x) do
if church(x[i]) then x[i] = tointch(x[i]) end if
end for
-- return call_func(rid,n&x)
x = deep_copy({n})&deep_copy(x)
return call_func(rid,x)
end function
constant church zero = {add,0,{0,1}}
function inttoch(integer i)
if i=0 then
return zero
else
return succ(inttoch(i-1))
end if
end function
church three = succ(succ(succ(zero))),
four = succ(three)
printf(1,"three -> %d\n",tointch(three))
printf(1,"four -> %d\n",tointch(four))
printf(1,"three + four -> %d\n",tointch(addch(three,four)))
printf(1,"three * four -> %d\n",tointch(mulch(three,four)))
printf(1,"three ^ four -> %d\n",tointch(powch(three,four)))
printf(1,"four ^ three -> %d\n",tointch(powch(four,three)))
printf(1,"5 -> five -> %d\n",tointch(inttoch(5)))