在类型类中键入约束

时间:2013-08-13 22:44:19

标签: haskell typeclass

为了好玩,我正在构建一个解析器库。在这个库中,我有一个Parser数据类型:

data Parser e a = Parser (String -> Either e (a, String))

我可以定义Functor的{​​{1}}和Applicative个实例,但我不认为我可以在不限制“错误”的情况下创建Parser个实例类型或解析器可以返回的“值”类型。最初,这使我在错误类型为Alternative消息时创建了Applicative实例,但我意识到我应该能够将此约束释放到具有{{1}的任何消息数据类型(或者也许String代替?)实例。考虑到这一点,我写了这个:

Alternative

不幸的是,这无法编译。当我将其加载到ghci时,我收到此错误消息:

Monoid

当我在网上搜索时,这似乎是解决方案,但它对我不起作用。我错过了什么?

1 个答案:

答案 0 :(得分:6)

问题是Alternative适用于类型* -> *的类型构造函数,所以如果你说

instance Alternative e => ....

然后e必须是类型构造函数,而不是类型。因此e可以是[]Maybe或其他内容,但不是Int

Alternative的运算符是<|>,其类型为Alternative e => e a -> e a -> e a。这迫使e采用参数来创建类型,如Maybe必须采用参数,例如Maybe Int

使用Monoid代替Alternative,因为它是类型类而不是构造函数类。它的运算符mappend具有类型Monoid e => e -> e -> e,这是组合错误所需的。