SHARE
TWEET

EP.hs

Tysonzero Dec 6th, 2019 154 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
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top