{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, NoMonomorphismRestriction #-} -- Simply typed LC class LAM1 r where lit1 :: t -> r t app1 :: r (a -> b) -> r a -> r b lam1 :: (r a -> r b) -> r (a -> b) -- One application is straightforward. t1 l = app1 (lam1 $ \a -> a) (lit1 l) -- Curried arguments of course need multiple lam1 constructors, and -- app1 constructons at application site. f1' = (lam1 $ \a -> (lam1 $ \b -> a)) t1' l = app1 (app1 f1' (lit1 l)) (lit1 l) -- Simply typed LC with only tail calls. This just limits the return -- type of the expression, so is not so interesting. class LAM2 x r | r -> x, x -> r where lit2 :: t -> r t app2 :: r (a -> x) -> r a -> r x lam2 :: (r a -> r x) -> r (a -> x) ret2 :: x -> r x -- Monadic LC class Monad m => LAM3 r m | r -> m where lit3 :: t -> r t app3 :: r (a -> m b) -> r a -> m (r b) lam3 :: (r a -> m (r b)) -> r (a -> m b) fn3 = lam3 (\a -> return a) t3 l = app3 fn3 (lit3 l) -- I don't see how to do multiple arguments though..