【问题标题】:Divide Int to Int in Haskell在 Haskell 中将 Int 划分为 Int
【发布时间】:2014-02-26 09:13:20
【问题描述】:

我想要一个从给定的分数列表中计算平均分数的函数。这是我到目前为止所做的:

getAverageRate :: [Int]->Int
getAverageRate marks = (fromIntegral (foldr (+) 0 marks))/(fromIntegral (length marks))

我要做的是通过使用“foldr”获取列表中所有标记的总和,然后除以“长度标记”。尽管我已经使用了“fromIntegral”,但这个错误仍然出现,我找不到问题。

No instance for (Fractional Int) arising from a use of `/'
Possible fix: add an instance declaration for (Fractional Int)
In the expression:
  (fromIntegral (foldr (+) 0 marks)) / (fromIntegral (length marks))
In an equation for `getAverageRate':
    getAverageRate marks
      = (fromIntegral (foldr (+) 0 marks))
        / (fromIntegral (length marks))

【问题讨论】:

  • 通过调用fromIntegral,您要求将Int 转换为其他类型。但是通过将函数的返回类型限制为Int,您煞费苦心地将那些Ints 转换为的类型是...Int

标签: haskell int


【解决方案1】:

问题是Int 代表一个整数,所以能够对其进行除法是没有意义的,因为大多数除法会产生不是整数的东西。

很高兴我们有div,这是整数除法,所以你可以这样做

 average :: [Int] -> Int
 average [] = error "Can't average an empty list"
 average xs = sum xs `div` length xs

如果你不想使用整数除法,那么我们可以做类似的事情

 average :: [Int] -> Double
 average xs = fromIntegral (sum xs) / fromIntegral (length xs)

这只是将所有内容提升为 Double 以进行除法。

最后,您可以选择一种舍入方法并使用您所拥有的

 average xs = round $ fromIntegral (sum xs) / fromIntegral (length xs)

(友好的邻居警告sum 是邪恶的并且使用foldl 而不是foldl',所以在使用长列表时请务必使用-O2 进行编译)

【讨论】:

  • 作为一个刚接触haskell的人,为什么sum是邪恶的?
  • @devshorts 它基于foldl,它可以在您意想不到的情况下进行堆栈溢出。它适用于 -O2 虽然搜索 foldl vs foldl'
  • 请原谅我在这里插话,但对于 Haskell 初学者,这里描述了为什么 foldl'foldl 更好。
  • @J.Abrahamson 我想你忘记了链接?我真的很喜欢一个好的教程,所以请分享:)
  • 哦,我做到了:stackoverflow.com/questions/20356742/… 谢谢你通知我
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-27
  • 1970-01-01
  • 2011-02-16
  • 2012-05-05
  • 1970-01-01
相关资源
最近更新 更多