我一直在尝试使用rank-2类型在PureScript中对GADT进行编码,如Haskell所述here
我的代码如下:
data Z
data S n
data List a n
= Nil (Z -> n)
| Cons forall m. a (List a m) (S m -> n)
fw :: forall f a. (Functor f) => (forall b . (a -> b) -> f b) -> f a
fw f = f id
bw :: forall f a. (Functor f) => f a -> (forall b . (a -> b) -> f b)
bw x f = map f x
nil :: forall a. List a Z
nil = fw Nil
cons :: forall a n. a -> List a (S n)
cons a as = fw (Cons a as)
instance listFunctor :: Functor (List a) where
map f (Nil k) = Nil (f <<< k)
map f (Cons x xs k) = Cons x xs (f <<< k)
编译器抱怨Wrong number of arguments to constructor Main.Cons
,引用Functor实例中的LHS模式匹配。
这里出了什么问题?
此致
迈克尔
答案 0 :(得分:5)
在PureScript中不存在用于Haskell中存在类型的语法。您为Cons
编写的内容是一个具有单一通用量化参数的数据构造函数。
您可能希望尝试使用purescript-exists
对存在类型进行编码。
另一种选择是使用GADT的最终无标记编码:
class Listy l where
nil :: forall a. l Z a
cons :: forall a n. a -> l n a -> l (S n) a
您可以为任何有效的Listy
实例编写术语:
myList :: forall l. (Listy l) => l (S (S Z)) Int
myList = cons 1 (cons 2 nil)
并通过编写实例来解释它们
newtype Length n a = Length Int
instance lengthListy :: Listy Length where
nil = Length 0
cons _ (Length n) = Length (n + 1)
newtype AsList n a = AsList (List a)
instance asListListy :: Listy AsList where
nil = AsList Nil
cons x (AsList xs) = AsList (Cons x xs)