packages feed

creditmonad-1.0.0: app/Stack.hs

module Stack where

fn :: Int -> (a -> a) -> a -> a
fn 0 f x = x
fn n f x = fn (n - 1) f (f x)

suc :: Int -> Int
suc n = n + 1

exp1 :: Int -> Int -> Int
exp1 m n = fn m (fn n) suc 0

--

data Fun b = Unit (b -> b) | Rec (Fun b) (Fun b -> b -> b)

call :: Fun b -> b -> b
call (Unit f) x = f x
call (Rec env f) x = f env x

fn' :: Int -> Fun b -> b -> b
fn' 0 f x = x
fn' n f x = fn' (n - 1) f (call f x)

fn1 :: Int -> Fun b -> Fun b
fn1 n f = Rec f (fn' n)

exp2 :: Int -> Int -> Int
exp2 m n = call (fn' m (Unit (fn1 n)) (Unit suc)) 0

--

data Closure b where
  Exists :: a -> (a -> b -> b) -> Closure b

callC :: Closure b -> b -> b
callC (Exists x f) y = f x y

fnC :: Int -> Closure b -> b -> b
fnC 0 c x = x
fnC n c x = fnC (n - 1) c (callC c x)

fnC1 :: Int -> Closure b -> Closure b
fnC1 n c = Exists c (fnC n)

fnC1' :: Int -> () -> Closure b -> Closure b
fnC1' n () c = fnC1 n c

sucC :: () -> Int -> Int
sucC () n = n + 1

exp3 :: Int -> Int -> Int
exp3 m n = callC (fnC m (Exists () (fnC1' n)) (Exists () sucC)) 0

--

-- type Closure b c = ... | Fn (type of env) (type of env -> b -> c) | ...
-- [[\x.^n e]] = (fn, env) where
--   fn env x = [[e]]
--   env = "free vars in [[e]]"