最佳答案
我和初学者 Haskell 一起玩,我想写一个平均函数。这似乎是世界上最简单的事情,对吧?
错了。
Haskell 的类型系统似乎禁止 average 处理泛型数字类型——我可以让它处理一个 Integrals 列表,或者一个分数类型列表,但不能同时处理这两个类型。
我想要:
average :: (Num a, Fractional b) => [a] -> b
average xs = ...
但我只能得到:
averageInt :: (Integral a, Fractional b) => [a] -> b
averageInt xs = fromIntegral (sum xs) / fromIntegral (length xs)
或者
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
和 either
来创建某种多态平均函数,可以在任何类型的数字数组上运行?
Haskell 的类型系统是否完全禁止这个函数的存在?
学习 Haskell 就像学习微积分。它真的很复杂,基于大量的理论,有时候这个问题是如此令人难以置信的复杂,以至于我甚至不知道如何正确地表达这个问题,所以任何见解都会被热烈地接受。
(另外,脚注: 这是基于一个家庭作业的问题。每个人都同意上面的 averageFrac 获得满分,但是我有一个潜在的怀疑,那就是有一种方法可以让它同时在整数和分数数组上工作)