如何定义一个参数为" newtype"的Haskell函数?

时间:2015-04-24 21:58:17

标签: haskell types newtype

我已经定义了一个名为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

1 个答案:

答案 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