/Generics1.hs

http://github.com/batterseapower/haskell-kata · Haskell · 143 lines · 107 code · 31 blank · 5 comment · 7 complexity · dc3eeb5428f4d5943b676f5f65a57300 MD5 · raw file

  1. {-# LANGUAGE TypeFamilies, EmptyDataDecls, ScopedTypeVariables #-}
  2. import Data.Monoid
  3. type family Force a :: *
  4. data Forced (a :: *)
  5. type instance Force (Forced a) = a
  6. newtype VarF var term value = AVar { unVar :: String }
  7. data TermF var term value
  8. = Var (Force var)
  9. | App (Force term) (Force var)
  10. | Value (Force value)
  11. | Add (Force term) (Force term)
  12. data ValueF var term value
  13. = Literal Int
  14. | Lambda String (Force term)
  15. data SyntaxAlgebra var term value = SyntaxAlgebra {
  16. varAlgebra :: VarF var term value -> Force var,
  17. termAlgebra :: TermF var term value -> Force term,
  18. valueAlgebra :: ValueF var term value -> Force value
  19. }
  20. type Fix3_1 f g h = f (FixTag3_1 f g h) (FixTag3_2 f g h) (FixTag3_3 f g h)
  21. type Fix3_2 f g h = g (FixTag3_1 f g h) (FixTag3_2 f g h) (FixTag3_3 f g h)
  22. type Fix3_3 f g h = h (FixTag3_1 f g h) (FixTag3_2 f g h) (FixTag3_3 f g h)
  23. data FixTag3_1 f g h
  24. data FixTag3_2 f g h
  25. data FixTag3_3 f g h
  26. type instance Force (FixTag3_1 f g h) = Fix3_1 f g h
  27. type instance Force (FixTag3_2 f g h) = Fix3_2 f g h
  28. type instance Force (FixTag3_3 f g h) = Fix3_3 f g h
  29. type Var = Fix3_1 VarF TermF ValueF
  30. type Term = Fix3_2 VarF TermF ValueF
  31. type Value = Fix3_3 VarF TermF ValueF
  32. -- TODO: try doing this as a functor category?
  33. fmap3VarF :: (Force var -> Force var')
  34. -> (Force term -> Force term')
  35. -> (Force value -> Force value')
  36. -> VarF var term value
  37. -> VarF var' term' value'
  38. fmap3VarF _var _term _value x = case x of
  39. AVar x -> AVar x
  40. fmap3TermF :: (Force var -> Force var')
  41. -> (Force term -> Force term')
  42. -> (Force value -> Force value')
  43. -> TermF var term value
  44. -> TermF var' term' value'
  45. fmap3TermF var term value e = case e of
  46. Var x -> Var (var x)
  47. App e x -> App (term e) (var x)
  48. Value v -> Value (value v)
  49. Add e1 e2 -> Add (term e1) (term e2)
  50. fmap3ValueF :: (Force var -> Force var')
  51. -> (Force term -> Force term')
  52. -> (Force value -> Force value')
  53. -> ValueF var term value
  54. -> ValueF var' term' value'
  55. fmap3ValueF _var term _value v = case v of
  56. Literal l -> Literal l
  57. Lambda x e -> Lambda x (term e)
  58. foldMap3VarF :: Monoid m
  59. => (Force var -> m)
  60. -> (Force term -> m)
  61. -> (Force value -> m)
  62. -> VarF var term value
  63. -> m
  64. foldMap3VarF _var _term _value x = case x of
  65. AVar _ -> mempty
  66. foldMap3TermF :: Monoid m
  67. => (Force var -> m)
  68. -> (Force term -> m)
  69. -> (Force value -> m)
  70. -> TermF var term value
  71. -> m
  72. foldMap3TermF var term value e = case e of
  73. Var x -> var x
  74. App e x -> term e `mappend` var x
  75. Value v -> value v
  76. Add e1 e2 -> term e1 `mappend` term e2
  77. foldMap3ValueF :: Monoid m
  78. => (Force var -> m)
  79. -> (Force term -> m)
  80. -> (Force value -> m)
  81. -> ValueF var term value
  82. -> m
  83. foldMap3ValueF _var term _value v = case v of
  84. Literal _ -> mempty
  85. Lambda _ e -> term e
  86. example :: Value
  87. example = Lambda "x" $ Add (Value (Literal 1)) (Var (AVar "x")) `App` AVar "x"
  88. -- fixAlgebra :: SyntaxAlgebra var term value -> SyntaxAlgebra (Fix3_1 var term value) (Fix3_2 var term value) (Fix3_3 var term value)
  89. -- fixAlgebra alg = undefined
  90. applyAlgebra :: forall var term value.
  91. SyntaxAlgebra var term value
  92. -> Term -> Force term
  93. -- -> SyntaxAlgebra (FixTag3_1 VarF TermF ValueF) (FixTag3_2 VarF TermF ValueF) (FixTag3_3 VarF TermF ValueF)
  94. applyAlgebra alg = {- SyntaxAlgebra var term value -- -} term
  95. where
  96. var :: Var -> Force var
  97. var = varAlgebra alg . fmap3VarF var term value
  98. term :: Term -> Force term
  99. term = termAlgebra alg . fmap3TermF var term value
  100. value :: Value -> Force value
  101. value = valueAlgebra alg . fmap3ValueF var term value
  102. instance Monoid Int where
  103. mempty = 0
  104. mappend = (+)
  105. main = print result
  106. where
  107. result = applyAlgebra alg (Value example)
  108. alg :: SyntaxAlgebra (Forced Int) (Forced Int) (Forced Int)
  109. alg = SyntaxAlgebra var term value
  110. var x = 1 + foldMap3VarF id id id x
  111. term e = 1 + foldMap3TermF id id id e
  112. value v = 1 + foldMap3ValueF id id id v