作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在玩一些 Haskell 代码。我定义了两个函数:
count :: [a] -> Int
count [] = 0
count (x:xs) = 1 + (count xs)
-- 03. Write a function that computes the mean of a list, i.e., the sum of all
-- elements in the list divided by its length. (You may need to use the
-- fromIntegralfunction to convert the length of the list from an integer
-- into a floating-point number.)
-- I've guessed this type definition, but it's incorrect:
-- listMean :: [a] -> Double
-- The following is the same inferred by hgci
listMean :: (Fractional a) => [a] -> a
listMean lst = (foldl1 (+) lst)/(fromIntegral (count lst))
为什么 [a] -> Double 不正确?似乎我给出的 lst 是某种类型 a 的通用列表,而 listMean 返回一个 Double。我做错了什么?
谢谢,阿尔弗雷多
最佳答案
首先,listMean::[a] -> Double
表示 listMean
是一个接受任意类型 a
列表的函数到单个 Double
值。
但是您依赖于能够将 (+)
应用于列表 (foldl1 (+)
) 的元素,这需要类型 a
是 Num
的实例,这意味着您至少有:
listMean :: (Num a) => [a] -> b
您还将 (/)
应用于 foldl1
操作产生的类型 a
的值。为此,a
必须不仅是 Num
的实例,而且是 Fractional
的实例。将此要求应用于类型 a
给出类型签名:
listMean :: (Fractional a) => [a] -> b
现在,b
呢?那么,(/)
的签名是 (/)::(Fractional a) => a -> a -> a
。因此,listMean
的结果也必须是 Fractional
的实例。此外,它必须与列表中包含的 Fractional
的实例相同:类型 b
因此实际上是类型 a
,并且listMean
最通用的签名是:
listMean :: (Fractional a) => [a] -> a
这正是编译器推断的。如果你想专门针对 Double
,你必须用 Double
替换 both 出现的 a
:
listMean :: [Double] -> Double
这是因为你没有运算符将 Fractional
的任何实例强制转换为 Double
,所以输入和输出都到 (/)
必须是 Double
类型。
关于Haskell 的类型关联链令人费解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4081053/
我是一名优秀的程序员,十分优秀!