我已经定义了一个名为Poly的新类型。 Poly是多项式的列表表示(Num的列表),我试图定义一个函数" chop"从Poly结束时取消多余的0。
Chop将一个Poly作为参数,然后返回Poly。出于某种原因,我收到以下错误消息:
预计有一个约束,但'Poly a'有点'*' 在'chop'的类型签名中:chop :: Poly a => a - >一个
newtype Poly a = P [a]
chop :: Poly a => a -> a
chop l = if (last l) == 0 then chop (init l) else l
答案 0 :(得分:10)
在Haskell中,类型签名中的=>
字符表示类型限制。这与Haskell类型类一起使用,以抽象出可以在高级抽象级别使用的函数的实现细节。
在您的示例中,根据类型系统,Poly a
是一个全新的类型,而不是类型类,因此您的函数chop
可能会直接对其进行操作:
chop :: Poly a -> Poly a
chop (P l) = if (last l) == 0 then chop (P $ init l) else P l
但是等等,这不会编译!限制来自与0:(last l) == 0
的比较。在这里,我们隐含地说我们希望Poly a
的元素与零相比,换句话说a
必须是Num a
的实例。毕竟,你不能砍掉Poly (Maybe String)
类型的多项式。我们修改的类型签名是:
chop :: Num a => Poly a -> Poly a
chop (P l) = if (last l) == 0 then chop (P $ init l) else P l
要考虑的一件事是:因为你使用的是newtype
而不是普通的type
,所以Haskell会将你的Poly a
视为一种全新的类型。为了使其可与列表互换,您可以使用类型同义词:
type Poly a = [a]
这将简化chop的实现:
chop :: Num a => Poly a -> Poly a
chop l = if (last l) == 0 then chop (init l) else l