首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell学习练习给出了奇怪的结果

Haskell学习练习给出了奇怪的结果
EN

Stack Overflow用户
提问于 2010-01-08 12:40:01
回答 7查看 569关注 0票数 6

这就是问题所在:

“编写一个计算列表平均值的函数,即列表中所有元素除以其长度的总和。(您可能需要使用fromIntegral函数将列表的长度从整数转换为浮点数)。”

首先我尝试了这个:

代码语言:javascript
复制
mean :: [Double] -> Double
mean []     = 0
mean (x:xs) = (x + mean xs) / (1 + mean xs)

但它给了我奇怪的结果,例如,当我这样使用它:

代码语言:javascript
复制
mean [2,4,6]  

它给我的结果是: 1.41176

应在何处:4

为什么?

我又试了一件事:

代码语言:javascript
复制
mean :: [Double] -> Double  
mean list = (summ list) / (count list)  
    where count []     = 0  
          count (x:xs) = 1 + count xs  
          summ []      = 0  
          summ (x:xs)  = x + summ xs

但是,当我试图将文件加载到GHC时,出现了一个错误。

错误是:

代码语言:javascript
复制
parse error on input 'count'  
Failed, modules loaded: none

再说一遍,我做错什么了?

最后,我尝试了这个(成功的):

代码语言:javascript
复制
mean :: [Double] -> Double

count []     = 0
count (x:xs) = 1 + count xs
summ  []     = 0
summ (x:xs)  = x + summ xs
mean list    = summ list / count list

它与上面的关键字相同(使用“where”关键字),但它只在这里成功,而在上面的关键字中没有成功。

为什么?

非常感谢。

附注:

我正在学习这本书--真实世界的哈斯克尔,这个练习来自这里 -(把它卷下来:-)

多亏了你们所有人。这是件奇怪的事。当我从这里复制并测试它时,第二个示例也适用于我。我不知道为什么昨天对我没用:-)

但我还是不明白为什么第一个不起作用。我觉得应该是那样

代码语言:javascript
复制
(2 + mean [4,6]) / (1 + mean [4,6])
(4 + mean [6  ]) / (1 + mean [  6])
(6 + mean [   ]) / (1 + mean [   ])      

所以现在是这样的

代码语言:javascript
复制
(6 +  0        )    / (1 +  0          )  -- last recursion
(4 + (6 + 0)   )    / (1 + (1 + 0)     )
(2 + (4 + (6 + 0))) / (1 + (1 + (1 + 0))

所以现在应该是: 12 /3

难到不是么?

我不明白的是什么?

谢谢:-)。

EN

回答 7

Stack Overflow用户

发布于 2010-01-08 13:03:06

  1. 你的第一次尝试得到了错误的答案,因为你使用了一个不正确的公式。垃圾进来,垃圾外泄。(其他人也讨论过这个问题。)
  2. 您可能会得到一个解析错误,因为有些行使用空格,而其他行使用制表符。或者您正在使用所有选项卡,但使用的是非标准选项卡宽度。
  3. 这里不使用缩进,也不需要缩进,所以空格-v-制表符问题不会出现。
票数 5
EN

Stack Overflow用户

发布于 2010-01-08 13:00:39

您的第一次尝试的结果如下:

代码语言:javascript
复制
6 / 1
4 + 6 / 1 + 6
2 + (10/7) / 1 + (10/7)

这不是你想要的。

第二次尝试很好。

票数 2
EN

Stack Overflow用户

发布于 2010-01-08 22:26:24

正确:

代码语言:javascript
复制
import Data.List (foldl')
mean :: Fractional a => [a] -> a
mean = uncurry (/) . foldl' (\(s, n) x -> (s + x, n + 1)) (0, 0)

mean [2,4,6] = uncurry (/) $ foldl' (...) (0, 0) [2,4,6]
             = uncurry (/) $ foldl' (...) (2, 1) [4,6]
             = uncurry (/) $ foldl' (...) (6, 2) [6]
             = uncurry (/) $ foldl' (...) (12, 3) []
             = uncurry (/) (12, 3)
             = 12 / 3
             = 4

不正确:

代码语言:javascript
复制
mean [] = 0
mean (x:xs) = (x + mean xs) / (1 + mean xs)

mean [6] = mean (6 : [])
         = (6 + mean []) / (1 + mean [])
         = (6 + 0) / (1 + 0)
         = 6
mean [4,6] = mean (4 : [6])
           = (4 + mean [6]) / (1 + mean [6])
           = (4 + 6) / (1 + 6)
           = 10/7
mean [2,4,6] = mean (2 : [4,6])
             = (2 + mean [4,6]) + (1 + mean [4,6])
             = (2 + 10/7) / (1 + 10/7)
             = 24/17
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2027570

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档