dma*_*man 4 haskell types newtype
我已经定义了一个名为Poly的新类型.Poly是多项式的列表表示(Num的列表),我正在尝试定义一个函数"chop",它从Poly的末尾取消多余的0.
Chop将一个Poly作为参数,然后返回Poly.出于某种原因,我收到以下错误消息:
期望一个约束,但'Poly a'在'chop'的类型签名中有'*'类型:chop :: Poly a => a - > a
newtype Poly a = P [a]
chop :: Poly a => a -> a
chop l = if (last l) == 0 then chop (init l) else l
Run Code Online (Sandbox Code Playgroud)
Mok*_*sha 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
Run Code Online (Sandbox Code Playgroud)
但是等等,这不编译!限制来自与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
Run Code Online (Sandbox Code Playgroud)
需要考虑的一件事是:因为你使用的是a newtype
而不是普通的旧版本type
,Haskell将你Poly a
视为一种全新的类型.为了使其可与列表互换,您可以使用类型同义词:
type Poly a = [a]
Run Code Online (Sandbox Code Playgroud)
这将简化chop的实现:
chop :: Num a => Poly a -> Poly a
chop l = if (last l) == 0 then chop (init l) else l
Run Code Online (Sandbox Code Playgroud)