Haskell 什么';这两种函数类型定义之间的区别是什么?
对于以下普通函数定义:Haskell 什么';这两种函数类型定义之间的区别是什么?,haskell,Haskell,对于以下普通函数定义: printLength1::(Num a)=>String->a printLength1 s = length s printLength2::String->Int printLength2 s = length s 为什么它们不一样?在什么情况下,我应该选择一种而不是另一种 对于printLength1,我得到了这个错误: Couldn't match type `a' with `Int' `a' is a rigid type
printLength1::(Num a)=>String->a
printLength1 s = length s
printLength2::String->Int
printLength2 s = length s
为什么它们不一样?在什么情况下,我应该选择一种而不是另一种
对于printLength1,我得到了这个错误:
Couldn't match type `a' with `Int'
`a' is a rigid type variable bound by
the type signature for rpnc :: String -> a at test.hs:20:1
In the return type of a call of `length'
In the expression: length s
In an equation for `rpnc': rpnc s = length s
我理解这个错误。但是我怎么才能解决这个问题呢?
我已经读过一些关于刚性类型变量的帖子,但仍然不明白如何修复它。引用:
注意:此函数的类型为numLongChains::Int,因为出于历史原因,length返回的是Int而不是Num a。如果我们想返回一个更一般的Num a,我们可以在得到的长度上使用fromIntegral
第一种类型的签名更一般。这意味着结果可以是任意
Num
——它的返回类型是多态的。因此,第一个函数的结果可以用作Int
或Integer
或任何其他Num
实例
问题是length
返回的是Int
而不是任何Num
实例。您可以使用积分中的来解决此问题:
printLength1 :: Num a => String -> a
printLength1 s = fromIntegral $ length s
请注意,fromIntegral的签名。长度
(这是上面代码的无点版本)是numc=>[a]->c
。这与您为printLength1
函数指定的签名匹配。谢谢。我希望语言中不再隐藏这样的怪癖。@osager这不是怪癖,这是类型系统中非常重要的一部分。多态类型(至少排名1的多态类型)通过使用方式转变为具体类型。如果您编写的类型签名声称类型是多态的,那么它实际上需要是多态的。Num
类不是一个怪癖,但是您可以合理地认为length
是一个Int
而不是Num a
是一个怪癖。Data.List.genericLength
具有类型Num a=>b]->a
@Grazer:很高兴知道。必须有一个特殊的length
通用版本这一事实正好说明这有点奇怪。