我正在尝试初学者 Haskell,我想编写一个平均函数。这似乎是世界上最简单的事情,对吧?
Wrong.
看起来 Haskell 的类型系统禁止平均值处理通用数字类型 - 我可以让它处理积分列表或分数列表,但不能同时处理两者。
I want:
average :: (Num a, Fractional b) => [a] -> b
average xs = ...
但我只能得到:
averageInt :: (Integral a, Fractional b) => [a] -> b
averageInt xs = fromIntegral (sum xs) / fromIntegral (length xs)
or
averageFrac :: (Fractional a) => [a] -> a
averageFrac xs = sum xs / fromIntegral (length xs)
第二个似乎有效。直到我尝试传递一个变量。
*Main> averageFrac [1,2,3]
2.0
*Main> let x = [1,2,3]
*Main> :t x
x :: [Integer]
*Main> averageFrac x
<interactive>:1:0:
No instance for (Fractional Integer)
arising from a use of `averageFrac ' at <interactive>:1:0-8
Possible fix: add an instance declaration for (Fractional Integer)
In the expression: average x
In the definition of `it': it = averageFrac x
显然,Haskell 对它的类型非常挑剔。这就说得通了。但当他们都可以成为[Num]时就不行了
我是否错过了 RealFrac 的一个明显应用?
有没有办法将积分强制转换为分数,并且在获得分数输入时不会阻塞?
有什么方法可以使用Either
and either
制作某种可以在任何类型的数值数组上工作的多态平均函数?
Haskell 的类型系统是否彻底禁止此函数存在?
学习 Haskell 就像学习微积分一样。它真的很复杂,并且基于大量的理论,有时问题是如此复杂,以至于我什至不知道如何正确地表达问题,所以任何见解都会被热烈接受。
(另外,脚注:这是基于家庭作业问题。每个人都同意上面的averageFrac获得满分,但我偷偷怀疑有一种方法可以让它在积分和分数数组上工作)