Advertisement
Guest User

Untitled

a guest
Jun 24th, 2017
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.09 KB | None | 0 0
  1. {-# LANGUAGE TemplateHaskell #-}
  2.  
  3. module Hamburger.TH where
  4.  
  5. import Language.Haskell.TH
  6.  
  7. type TypeName = String
  8.  
  9. type Topping4 = (TypeName, TypeName, TypeName, TypeName)
  10.  
  11.  
  12. topping4s :: [Topping4]
  13. topping4s = [(w, x, y, z) | w <- toppings, x <- toppings, y <- toppings, z <- toppings]
  14. where
  15. toppings :: [TypeName]
  16. toppings = ["Space", "Cheese", "Tomato", "Meet", "Ushi"]
  17.  
  18. -- | Make a AST of @Type@ is like "(HamburgerC Space Cheese Tomato Meet)"
  19. hamburgerC :: Topping4 -> Type
  20. hamburgerC (w, x, y, z) = ParensT (ConT (mkName "HamburgerC")
  21. `AppT` ConT (mkName w)
  22. `AppT` ConT (mkName x)
  23. `AppT` ConT (mkName y)
  24. `AppT` ConT (mkName z))
  25.  
  26. -- |
  27. -- Make a AST of @Exp@ is like "Concrete SSpace SCheese STomato SMeet"
  28. -- (@Topping4@ elements are added "S" prefix for @STopping@).
  29. concrete :: Topping4 -> Exp
  30. concrete (w, x, y, z) = ConE (mkName "Concrete")
  31. `AppE` ConE (mkName $ "S" ++ w)
  32. `AppE` ConE (mkName $ "S" ++ x)
  33. `AppE` ConE (mkName $ "S" ++ y)
  34. `AppE` ConE (mkName $ "S" ++ z)
  35.  
  36.  
  37. -- | Define @Singleton@ instances and @Show@ instances for any pattern of @topping4@
  38. defineInstances :: DecsQ
  39. defineInstances = do
  40. let singletonInstances = map defineSingletonInstance topping4s
  41. showInstances = map defineShowInstance topping4s
  42. return $ singletonInstances ++ showInstances
  43. where
  44. defineSingletonInstance :: Topping4 -> Dec
  45. defineSingletonInstance t4@(w, x, y, z) =
  46. InstanceD Nothing []
  47. (ConT (mkName "Singleton") `AppT` hamburgerC t4)
  48. [
  49. FunD (mkName "sing") [Clause [] (NormalB $ concrete t4) []]
  50. ]
  51.  
  52. defineShowInstance :: Topping4 -> Dec
  53. defineShowInstance t4@(w, x, y, z) =
  54. InstanceD Nothing []
  55. (ConT (mkName "Show") `AppT` ParensT (ConT (mkName "SHamburger") `AppT` hamburgerC t4))
  56. [
  57. FunD (mkName "show") [Clause [WildP] (NormalB $
  58. LitE $ StringL "SHamburger (" ++ w ++ " " ++ x ++ " " ++ y ++ " " ++ z ++ ")"
  59. ) []]
  60. ]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement