开发者

Haskell datatype conversion problems

I am currently learning Haskell and have been writing a couple of very simple programs to practice as I go along. One of these programs is the one I have bellow:

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)

What it does is take a year after 2010 and calculate the estimated population in that year, and as it is right now it works fine and all except that as you may have noticed EVERY single number is cast as a float. Now it is pretty ridiculous to do this since there is no reason to have the current population, the number of seconds in a year or the year itself for that matter as anything but ints, unfortunately though when I had it that way I was getting compiler error with the / function saying something about开发者_JAVA百科 fractional int and with the * function saying it inferred a float as the first parameter. Now I had understood that Haskell like other languages when encountering operations involving ints and floats would just change the int to act like a float which aperantly didn't happen here. Could someone explain why I was getting these errors and how I can get ints and floats to cooperate since evidently I still don't have a good enough grasp of the Haskell type system to do it myself?


Haskell types are strict; it never automatically converts a type for you, except that integer literals are automatically wrapped in fromIntegral. Instead, you may want to use more type-appropriate operations such as `div` when you only need to deal with Int/Integer, and fromIntegral to promote to Float or Double when needed.

(Syntax note: `function` converts a prefix function into an infix operator.)


For integer division in Haskell you use div or quot.


From the Haskell 98 language report:

An integer literal represents the application of the function fromInteger to the appropriate value of type Integer. Similarly, a floating point literal stands for an application of fromRational to a value of type Rational (that is, Ratio Integer).

This means a "7" in the source code becomes "(fromInteger 7)" and "1.5" becomes "(fromRational (3 Ratio.% 2))". The numerical operations such as (+) and (/) have type signatures like "a->a->a" meaning they two arguments of perfectly identical types and return the same type as given. These standard operators can never do things like add a Float to an Int. You can write a (fromIntegral) to try and promote an Int-like-type to things like a Double or Float.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜