繁体   English   中英

为什么haskell中的这个平均功能不起作用?

[英]Why doesn't this average function in haskell work?

我想在Haskell中创建一个简单的平均(平均)函数,所以我在ghci中尝试了以下内容:

ghci> let avg xs = (sum xs) / (length xs)

它会引发以下错误:

No instance for (Fractional Int)
  arising from a use of `/'
Possible fix: add an instance declaration for (Fractional Int)
In the expression: (sum xs) / (length xs)
In an equation for `avg': avg xs = (sum xs) / (length xs)

所以,我决定通过尝试以下方法将其分解:

ghci> let a = (sum [1,2])
ghci> let b = (length [1,2])

这一切都很好。

那么我尝试了以下内容

ghci> a/b

我收到以下错误:

Couldn't match expected type `Integer' with actual type `Int'
In the second argument of `(/)', namely `b'
In the expression: a / b
In an equation for `it': it = a / b

那么,在Haskell中IntegerInt不同? - 如果是这样,我怎样才能使原始功能起作用?

问题是

length :: [a] -> Int

(/) :: (Fractional a) => a -> a -> a

所以,当你说whatever / length xs ,它不会输入,因为Int不是分数数字类型! 这就是“No instance for ...”错误试图告诉你的。 这个定义可行:

GHCi> let avg xs = sum xs / fromIntegral (length xs)

这里,我们使用fromIntegral :: (Integral a, Num b) => a -> b将我们从length得到的Int转换为小数。 请注意,由此产生的函数仅适用于小数的列表(但例如avg [1,2,3]仍然可以正常工作)。

为了解释你在“分片”中所做的错误,这是因为在let a = sum [1,2] ,列表的元素是整数,所以它们的和是一个整数,但是在let b = length [1,2] ,根据我在上面显示的length类型,得到的长度是一个Int。 因此,当你执行a/b ,这会失败,直到它意识到Int和Integer不是Fractional的实例 - 因为(/)接受两个相同类型的参数,它不可能工作。

是的,Integer和Int是不同的 - Int是一个固定精度的整数类型,通常是数字的大小,就像C中的long一样,而Integer是一个任意精度的bignum,能够存储任何整数; 或者至少,任何适合你的RAM的整数:)

另一种可能的方法是使用Data.List.genericLengthavg xs定义为sum xs / genericLength xs ,它可以使用任何数字类型,而不仅仅是Ints:

genericLength :: (Num b) => [a] -> b

为此,您必须在GHCi中import Data.List 另一种可能的方法(但一个导致完全不同的功能)将是使用整数除法: let avg xs = sum xs `div` length xs (注意: a `div` b只是div ab ;这个句法糖用于每个功能)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM