Haskell 为什么';这不是哈斯克尔式签名作品吗?
哈斯克尔的新人。我正在努力提高写类型签名的能力,但这个简单的签名不起作用。我想知道为什么:Haskell 为什么';这不是哈斯克尔式签名作品吗?,haskell,types,type-signature,Haskell,Types,Type Signature,哈斯克尔的新人。我正在努力提高写类型签名的能力,但这个简单的签名不起作用。我想知道为什么: average :: Num a => [a] -> a average ns = sum ns `div` length ns 平均值应该取任意数并返回某个数。但是我得到了错误 test.hs 11:27: Couldn't match expected type 'a' with actual type 'Int' 'a' is a rigid type varia
average :: Num a => [a] -> a
average ns = sum ns `div` length ns
平均值应该取任意数并返回某个数。但是我得到了错误
test.hs 11:27:
Couldn't match expected type 'a' with actual type 'Int'
'a' is a rigid type variable bound by
the type signature for average :: Num a => [a] -> a
at test.hs:10:12
Relevant bindings include
ns:: [a] (bound at test.hs:11:9)
average :: [a] -> a (bound at test.hs:11:1)
In the second argument of 'div' namely 'length ns'
In the expression: sum ns `div ` length ns
它似乎在说长度并没有达到它的预期。有人能帮忙吗 好,这将起作用:
average :: Integral a => [a] -> a
average ns = sum ns `div` (fromIntegral $ length ns)
请注意div::Integral a=>a->a->a
,因此您需要Integral a
,而不仅仅是Num a
(没有除法)
因为length
将返回一个Int
,所以您需要使用integral中的来解决它。好,这将起作用:
average :: Integral a => [a] -> a
average ns = sum ns `div` (fromIntegral $ length ns)
请注意div::Integral a=>a->a->a
,因此您需要Integral a
,而不仅仅是Num a
(没有除法)
因为length
将返回一个Int
,所以您需要from Integral
来解决它。div
的类型是Integral a=>a->a->a
,这意味着它的两个参数必须是相同的类型。在这种情况下,第二个参数的类型始终为Int
(长度的结果),但第一个参数的类型为a
此外,您正在尝试编写一个适用于任何类型的Num
,但div
仅适用于整数类型的函数。如果要支持整数值的“平均”列表(结果也被舍入为整数),可以执行以下操作:
average :: Integral a => [a] -> a
average ns = sum ns `div` fromIntegral (length ns)
来自integral的将Int
长度转换为a
的任何整数类型(可能是Int
,或类似于Integer
)
为避免舍入错误,您需要对分数类型使用分数除法:
average :: Fractional a => [a] -> a
average ns = sum ns / fromIntegral (length ns)
div
的类型是Integral a=>a->a->a
,这意味着它的两个参数必须是相同的类型。在这种情况下,第二个参数的类型始终为Int
(长度的结果),但第一个参数的类型为a
此外,您正在尝试编写一个适用于任何类型的Num
,但div
仅适用于整数类型的函数。如果要支持整数值的“平均”列表(结果也被舍入为整数),可以执行以下操作:
average :: Integral a => [a] -> a
average ns = sum ns `div` fromIntegral (length ns)
来自integral
的将Int
长度转换为a
的任何整数类型(可能是Int
,或类似于Integer
)
为避免舍入错误,您需要对分数类型使用分数除法:
average :: Fractional a => [a] -> a
average ns = sum ns / fromIntegral (length ns)
其他答案很好地突出了Num
与Integral
的问题,即在调用length
后使用强制转换。或者,您可以使用数据中的genericlelength
。列表
:
import Data.List
average :: Integral a => [a] -> a
average ns = sum ns `div` genericLength ns
其他答案很好地突出了Num
与Integral
的问题,即在调用length
后使用强制转换。或者,您可以使用数据中的genericlelength
。列表
:
import Data.List
average :: Integral a => [a] -> a
average ns = sum ns `div` genericLength ns
这是因为length ns
是一个Int
但是div
适用于Integral a=>a->a->a
-试试average ns=sum ns
div`(from Integral$length ns)`-它应该可以工作,但在小事情上:div
无论如何都需要Integral
<代码>长度::[q]->Int
所以平均值::[Int]->Int
这是因为长度ns
是一个Int
但是div
适用于积分a=>a->a
尝试平均ns=sum ns
div`(from Integral$length ns)`-它应该可以工作,但在小事情上:div
无论如何都需要Integral
<代码>长度::[q]->Int所以平均值::[Int]->Int
。嗯,我甚至没有想过使用:type来确定div是什么。谢谢你的帮助NP-数字和它们的关系/转换总是让我着迷-真正的乐趣从浮动、罪恶等开始;)嗯,我甚至没有想过使用:type来确定div是什么。谢谢你的帮助NP-数字和它们的关系/转换总是让我着迷-真正的乐趣从浮动、罪恶等开始;)好的观点-我确实忘记了也许div
不是最好的主意;)好的观点-我确实忘记了也许div
不是最好的主意;)