2011-03-26 92 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之類的東西。