mirror of
https://github.com/sdiehl/write-you-a-haskell.git
synced 2024-09-11 11:46:57 +03:00
32 lines
738 B
Haskell
32 lines
738 B
Haskell
{-# LANGUAGE GADTs #-}
|
|
|
|
data Expr a where
|
|
Lift :: a -> Expr a
|
|
Tup :: Expr a -> Expr b -> Expr (a, b)
|
|
Lam :: (Expr a -> Expr b) -> Expr (a -> b)
|
|
App :: Expr (a -> b) -> Expr a -> Expr b
|
|
Fix :: Expr (a -> a) -> Expr a
|
|
|
|
eval :: Expr a -> a
|
|
eval (Lift v) = v
|
|
eval (Tup e1 e2) = (eval e1, eval e2)
|
|
eval (Lam f) = \x -> eval (f (Lift x))
|
|
eval (App e1 e2) = (eval e1) (eval e2)
|
|
eval (Fix f) = (eval f) (eval (Fix f))
|
|
|
|
fact :: Expr (Integer -> Integer)
|
|
fact =
|
|
Fix (
|
|
Lam (\f ->
|
|
Lam (\y ->
|
|
Lift (
|
|
if eval y == 0
|
|
then 1
|
|
else eval y * (eval f) (eval y - 1)))))
|
|
|
|
test :: Integer
|
|
test = eval fact 10
|
|
|
|
main :: IO ()
|
|
main = print test
|