Guest User

Untitled

a guest
Jun 24th, 2018
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.42 KB | None | 0 0
  1. data UnitT = Unit deriving Show
  2. data Sum aT bT = Inl aT | Inr bT deriving Show
  3. data Prod aT bT = Prod aT bT deriving Show
  4.  
  5. data EP bT cT = EP {from :: (bT -> cT), to :: (cT -> bT)}
  6.  
  7. data Rep tT where
  8. RUnit :: Rep UnitT
  9. RInt :: Rep Int
  10. RChar :: Rep Char
  11. RSum :: Rep aT -> Rep bT -> Rep (Sum aT bT)
  12. RProd :: Rep aT -> Rep bT -> Rep (Prod aT bT)
  13. RString :: Rep String
  14. RCon :: String -> Rep aT -> Rep aT
  15. RType :: EP bT cT -> Rep cT -> Rep bT
  16.  
  17. type RepAlgebra r = (r
  18. ,r
  19. ,r
  20. ,r
  21. ,forall a b. a -> b -> r
  22. ,forall a b. a -> b -> r
  23. ,forall a . String -> a -> r
  24. ,forall a b. EP a b -> r -> r
  25. )
  26.  
  27. -- This works, but is extremely bloated, ugly, and plain yuk
  28. foldRep :: RepAlgebra r -> Rep a -> r
  29. foldRep a@(unit, int, char, string, sum, prod, con, t) (RUnit) = unit
  30. foldRep a@(unit, int, char, string, sum, prod, con, t) (RInt) = int
  31. foldRep a@(unit, int, char, string, sum, prod, con, t) (RChar) = char
  32. foldRep a@(unit, int, char, string, sum, prod, con, t) (RString) = string
  33. foldRep a@(unit, int, char, string, sum, prod, con, t) (RSum ra rb) = sum (foldRep a ra) (foldRep a rb)
  34. foldRep a@(unit, int, char, string, sum, prod, con, t) (RProd ra rb) = prod (foldRep a ra) (foldRep a rb)
  35. foldRep a@(unit, int, char, string, sum, prod, con, t) (RCon l ra) = con l (foldRep a ra)
  36. foldRep a@(unit, int, char, string, sum, prod, con, t) (RType ep ra) = t ep (foldRep a ra)
  37.  
  38. -- This doesn't compile:
  39. foldRep' :: RepAlgebra r -> Rep a -> r
  40. foldRep' (unit, int, char, string, sum, prod, con, t) = f
  41. where
  42. f (RUnit) = unit
  43. f (RInt) = int
  44. f (RChar) = char
  45. f (RString) = string
  46. f (RSum ra rb) = sum (f ra) (f rb)
  47. f (RProd ra rb) = prod (f ra) (f rb)
  48. f (RCon l ra) = con l (f ra)
  49. f (RType ep ra) = t ep (f ra)
  50. {-
  51.  
  52. GADT pattern match in non-rigid context for `RUnit'
  53. Probable solution: add a type signature for `f'
  54. In the pattern: RUnit
  55. In the definition of `f': f (RUnit) = unit
  56. In the definition of `foldRep':
  57. foldRep (unit, int, char, string, sum, prod, con, t)
  58. = f
  59. where
  60. f (RUnit) = unit
  61. f (RInt) = int
  62. f (RChar) = char
  63. f (RString) = string
  64. f (RSum ra rb) = sum (f ra) (f rb)
  65. f (RProd ra rb) = prod (f ra) (f rb)
  66. f (RCon l ra) = con l (f ra)
  67. f (RType ep ra) = t ep (f ra)
  68. -}
  69.  
  70. -- Adding the type doesn't help, how can I convince the compiler that r in the type of f is the same as in the type of foldRep'?
  71.  
  72. foldRep' :: RepAlgebra r -> Rep a -> r
  73. foldRep' (unit, int, char, string, sum, prod, con, t) = f
  74. where f :: Rep a -> r
  75. f (RUnit) = unit
  76. f (RInt) = int
  77. f (RChar) = char
  78. f (RString) = string
  79. f (RSum ra rb) = sum (f ra) (f rb)
  80. f (RProd ra rb) = prod (f ra) (f rb)
  81. f (RCon l ra) = con l (f ra)
  82. f (RType ep ra) = t ep (f ra)
  83.  
  84. {-
  85. Couldn't match expected type `r1' against inferred type `r'
  86. `r1' is a rigid type variable bound by
  87. the type signature for `f' at gadtalgebra.hs:67:22
  88. `r' is a rigid type variable bound by
  89. the type signature for `foldRep'' at gadtalgebra.hs:65:23
  90. In the expression: t ep (f ra)
  91. In the definition of `f': f (RType ep ra) = t ep (f ra)
  92. In the definition of `foldRep'':
  93. foldRep' (unit, int, char, string, sum, prod, con, t)
  94. = f
  95. where
  96. f :: Rep a -> r
  97. f (RUnit) = unit
  98. f (RInt) = int
  99. f (RChar) = char
  100. f (RString) = string
  101. f (RSum ra rb) = sum (f ra) (f rb)
  102. f (RProd ra rb) = prod (f ra) (f rb)
  103. f (RCon l ra) = con l (f ra)
  104. f (RType ep ra) = t ep (f ra)
  105. -}
  106.  
  107. -- And now with the ScopedTypeVariables extension:
  108. foldRep' :: forall r a. RepAlgebra r -> Rep a -> r
  109. foldRep' (unit, int, char, string, sum, prod, con, t) = f
  110. where f :: Rep a -> r
  111. f (RUnit) = unit
  112. f (RInt) = int
  113. f (RChar) = char
  114. f (RString) = string
  115. f (RSum ra rb) = sum (f ra) (f rb)
  116. f (RProd ra rb) = prod (f ra) (f rb)
  117. f (RCon l ra) = con l (f ra)
  118. f (RType ep ra) = t ep (f ra)
  119. {-
  120. Occurs check: cannot construct the infinite type: aT = Sum aT bT
  121. In the pattern: RSum ra rb
  122. In the definition of `f': f (RSum ra rb) = sum (f ra) (f rb)
  123. In the definition of `foldRep'':
  124. foldRep' (unit, int, char, string, sum, prod, con, t)
  125. = f
  126. where
  127. f :: Rep a -> r
  128. f (RUnit) = unit
  129. f (RInt) = int
  130. f (RChar) = char
  131. f (RString) = string
  132. f (RSum ra rb) = sum (f ra) (f rb)
  133. f (RProd ra rb) = prod (f ra) (f rb)
  134. f (RCon l ra) = con l (f ra)
  135. f (RType ep ra) = t ep (f ra)
  136. -}
Add Comment
Please, Sign In to add comment