2011-03-26 182 views
2

我目前正在学习Haskell,并一直在编写几个非常简单的程序来练习。其中一项方案是一个我怒吼:Haskell数据类型转换问题

import System.IO 

main = do 
    putStrLn "Give me year: " 
    y <- getLine 
    let res = show . calcPop $ read y 
    putStrLn ("Population in " ++ y ++ " will be " ++ res) 



pop :: Float 
pop = 307357870.0 
secInYear :: Float 
secInYear = 365.0 * 24.0 * 60.0 * 60.0 
bRate :: Float 
bRate = secInYear/7.0 
dRate :: Float 
dRate = secInYear/13.0 
iRate :: Float 
iRate = secInYear/35.0 

calcPop :: Float -> Float 
calcPop year = let years = year - 2010 in (years*bRate + years*iRate + pop - years*dRate) 

它什么是需要2010年后并于当年计算估计的人口,而且因为它是现在它工作正常,所有不同的是如你可能已经注意到每个单个数字都被当作一个浮点数。现在做这件事非常荒谬,因为没有理由拥有当前的人口数量,一年中的秒数或一年中的秒数,除此之外,不幸的是,当我拥有这种方式时,我得到了编译器/函数错误地提供了关于小数整数的函数以及*函数说明它将浮点数推断为第一个参数。现在我已经理解Haskell像其他语言一样,遇到涉及int和float的操作时只会改变int的行为,就像在这里没有发生的float一样。有人能解释为什么我会得到这些错误,以及我如何能够通过合作和浮动来进行合作,因为显然我还没有很好地掌握Haskell类型系统来自己做这件事。

回答

9

Haskell类型是严格的;它从来没有自动转换为您的类型,除了整数文字自动包装在fromIntegral。相反,如果您需要处理Int/IntegerfromIntegral以促销FloatDouble,则可能需要使用更多类型相应的操作,例如`div`

(语法注:`function`转换前缀功能于缀运算符。)

2

对于哈斯克尔您使用divquot整数除法。

2

Haskell 98 language report

字面的整数表示 应用功能 fromInteger到Integer类型的适当的值 。类似地,浮点数 点文字代表从Rational的 应用程序到Rational类型的值 (即比率 整数)。

这意味着一个码成为源 “(fromInteger 7)” 和 “1.5” 变为 “7” “(fromRational(3比率。%2))”。像(+)和(/)这样的数字操作具有类型签名,如“a-> a-> a”,意味着它们具有完全相同类型的两个参数,并返回与给定类型相同的类型。这些标准的运算符永远不会像添加一个Float到Int一样。您可以编写一个(fromIntegral)来尝试将类似Int的类型提升为Double或Float之类的东西。