我定义了一个名为 Poly 的新类型。 Poly 是多项式的列表表示(Num 的列表),我试图定义一个函数“chop”,它从 Poly 的末尾去掉多余的 0。
Chop 将一个 Poly 作为参数,然后返回一个 Poly。出于某种原因,我收到以下错误消息:
Expected a constraint, but ‘Poly a’ has kind ‘*’ In the type signature for ‘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
最佳答案
在 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
关于haskell - 如何定义一个参数为 "newtype"的 Haskell 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29858217/