在Haskell中过度使用fromIntegral

时间:2010-08-10 21:31:12

标签: haskell integer double

每当我使用双精度和整数编写函数时,我发现这个问题,我不断在我的函数中到处使用'fromIntegral'。例如:

import Data.List

roundDouble
    :: Double
    -> Int 
    -> Double
roundDouble x acc = fromIntegral (round $ x * 10 ** fromIntegral acc) / 10 ** fromIntegral acc

有没有更简单的方法来写这个? (我知道可能有更简单的方法来舍入一个数字,如果有,请告诉我!但我主要感兴趣的是如何避免使用这么多'fromIntegrals'。)

谢谢,Ash

4 个答案:

答案 0 :(得分:24)

有时候我发现辅助函数很有用:

roundDouble x acc = (round $ x * 10 ^ acc) /. (10 ^ acc)
    where 
    x /. y = fromIntegral x / fromIntegral y

也可以写出辅助函数:

(/.) = (/) `on` fromIntegral

on来自Data.Function

答案 1 :(得分:12)

您可以使用^代替**^将任何积分作为第二个参数,因此您无需在第二个操作数上调用fromIntegral。所以你的代码变成了:

roundDouble x acc = fromIntegral(round $ x * 10 ^ acc)/ 10 ^ acc

只有一个fromIntegral。那个你无法摆脱的round自然会返回一个积分,你不能对积分进行非整数除法。

答案 2 :(得分:6)

我在编组代码方面遇到了类似的问题,其中fromIntegral用于将CInt转换为Int。我通常定义fI = fromIntegral以使其更容易。您可能还需要为其提供显式类型签名或使用-XNoMonomorphismRestriction。

如果你正在做大量的数学运算,你可能想看看Numeric Prelude,它似乎在不同的数字类型之间有更明智的关系。

答案 3 :(得分:4)

另一个想法,类似于luqui's。我对fromIntegral的大部分问题都与IntDoubleDouble的必要性有关。因此,此Int允许划分任何两种(/.)类型,不一定相同,不一定是{lu}的解决方案中的Real类型:

Integral

示例:

(/.) :: (Real a, Real b, Fractional c) => a -> b -> c
(/.) x y = fromRational $ (toRational x) / (toRational y)

它适用于任何两个ghci> let (a,b,c) = (2::Int, 3::Double, 5::Int) ghci> (b/.a, c/.a, a/.c) (1.5,2.5,0.4) ,但我怀疑合理划分和转换为Real并不是非常有效。

现在你的例子变成了:

Rational