OK, so I'm trying to implement the basics of lambda calculus. Here it goes.
My numbers:
def zero[Z](s: Z => Z)(z: Z): Z = z
def one[Z](s: Z => Z)(z: Z): Z = s(z)
def two[Z](s: Z => Z)(z: Z): Z = s(s(z))
Partially (actually, non) applied version of them is smth like that:
def z[Z]: (Z => Z) => (Z => Z) = zero _
Before I continue I define some types:
type FZ[Z] = Z => Z
type FFZ[Z] = FZ[Z] => FZ[Z]
Fine, succ
function goes like (Application order should be exactly like that! I took the definition here):
def succ[Z](w: FFZ[Z])(y: FZ[Z])(x: Z): Z = y((w(y))(x))
And the unapplied version of it gets as scary as:
def s[Z]: FFFZ[Z] = successor _
Beg your pardon, here is the missing types:
type FFFZ[Z] = FFZ[Z] => FFZ[Z]
type FFFFZ[Z] = FFFZ[Z] => FFFZ[Z]
But I'm stuck at the add
function. If conformed to types and definition (taken here as well) it goes like
def add[Z](a: FFFFZ[Z])(b: FFZ[Z]): FFZ[Z] =
(a(s))(b)
But I want a
to be a common number of type FFZ[Z]
.
So -- how can I define addition?
f
whose argument type is, say,a: Z -> Z
and it might not not exactly conform to a functionf': (Z -> Z) -> (Z -> Z)
I apply it to. – Updo