Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Exp
- data Exp c where
- Exp :: c e => e (Exp c) -> Exp c
- -- Lit/Add
- newtype Lit a = Lit Int
- lit :: c Lit => Int -> Exp c
- lit n = Exp (Lit n)
- data Add a = Add a a
- add :: c Add => Exp c -> Exp c -> Exp c
- add a b = Exp (Add a b)
- -- Eval
- class Eval e where
- eval_ :: e (Exp Eval) -> Int
- eval :: Exp Eval -> Int
- eval (Exp e) = eval_ e
- -- Eval for Lit/Add
- instance Eval Lit where
- eval_ (Lit x) = x
- instance Eval Add where
- eval_ (Add a b) = eval a + eval b
- -- Sub
- data Sub a = Sub a a
- sub :: c Sub => Exp c -> Exp c -> Exp c
- sub a b = Exp (Sub a b)
- -- Eval for Sub
- instance Eval Sub where
- eval_ (Sub a b) = eval a - eval b
- -- Render
- class Render e where
- render_ :: e (Exp Render) -> String
- render :: Exp Render -> String
- render (Exp e) = render_ e
- -- Render for Lit/Add
- instance Render Lit where
- render_ (Lit x) = show x
- instance Render Add where
- render_ (Add a b) = "(" ++ render a ++ " + " ++ render b ++ ")"
- -- Examples
- foo :: c Lit => Exp c
- foo = lit 5
- evalFoo :: Int
- evalFoo = eval foo
- renderFoo :: String
- renderFoo = render foo
- bar :: (c Add, c Lit) => Exp c
- bar = add foo (lit 8)
- evalBar :: Int
- evalBar = eval foo
- renderBar :: String
- renderBar = render bar
- baz :: (c Add, c Sub, c Lit) => Exp c
- baz = sub bar foo
- evalBaz :: Int
- evalBaz = eval baz
- allThree :: (c Add, c Sub, c Lit) => [Exp c]
- allThree = [foo, bar, baz]
- evalAllThree :: [Int]
- evalAllThree = eval <$> allThree
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement