Advertisement
Tysonzero

EP.hs

Dec 6th, 2019
959
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Exp
  2.  
  3. data Exp c where
  4.     Exp :: c e => e (Exp c) -> Exp c
  5.  
  6.  
  7. -- Lit/Add
  8.  
  9. newtype Lit a = Lit Int
  10.  
  11. lit :: c Lit => Int -> Exp c
  12. lit n = Exp (Lit n)
  13.  
  14. data Add a = Add a a
  15.  
  16. add :: c Add => Exp c -> Exp c -> Exp c
  17. add a b = Exp (Add a b)
  18.  
  19.  
  20. -- Eval
  21.  
  22. class Eval e where
  23.     eval_ :: e (Exp Eval) -> Int
  24.  
  25. eval :: Exp Eval -> Int
  26. eval (Exp e) = eval_ e
  27.  
  28.  
  29. -- Eval for Lit/Add
  30.  
  31. instance Eval Lit where
  32.     eval_ (Lit x) = x
  33.  
  34. instance Eval Add where
  35.     eval_ (Add a b) = eval a + eval b
  36.  
  37.  
  38. -- Sub
  39.  
  40. data Sub a = Sub a a
  41.  
  42. sub :: c Sub => Exp c -> Exp c -> Exp c
  43. sub a b = Exp (Sub a b)
  44.  
  45.  
  46. -- Eval for Sub
  47.  
  48. instance Eval Sub where
  49.     eval_ (Sub a b) = eval a - eval b
  50.  
  51.  
  52. -- Render
  53.  
  54. class Render e where
  55.     render_ :: e (Exp Render) -> String
  56.  
  57. render :: Exp Render -> String
  58. render (Exp e) = render_ e
  59.  
  60.  
  61. -- Render for Lit/Add
  62.  
  63. instance Render Lit where
  64.     render_ (Lit x) = show x
  65.  
  66. instance Render Add where
  67.     render_ (Add a b) = "(" ++ render a ++ " + " ++ render b ++ ")"
  68.  
  69.  
  70. -- Examples
  71.  
  72. foo :: c Lit => Exp c
  73. foo = lit 5
  74.  
  75. evalFoo :: Int
  76. evalFoo = eval foo
  77.  
  78. renderFoo :: String
  79. renderFoo = render foo
  80.  
  81. bar :: (c Add, c Lit) => Exp c
  82. bar = add foo (lit 8)
  83.  
  84. evalBar :: Int
  85. evalBar = eval foo
  86.  
  87. renderBar :: String
  88. renderBar = render bar
  89.  
  90. baz :: (c Add, c Sub, c Lit) => Exp c
  91. baz = sub bar foo
  92.  
  93. evalBaz :: Int
  94. evalBaz = eval baz
  95.  
  96. allThree :: (c Add, c Sub, c Lit) => [Exp c]
  97. allThree = [foo, bar, baz]
  98.  
  99. evalAllThree :: [Int]
  100. evalAllThree = eval <$> allThree
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement