2009-12-28 120 views
8

我正在學習Haskell。我已經創建了函數,它返回乘法表到'b'的基數'n'。數字填充爲'w'數字。作爲最後一步,我想自動計算'w'。爲什麼不能編譯?沒有實例(浮動INT)

-- Number of digits needed for the multiplication table n*n in base 'base' 
nOfDg :: Int -> Int-> Int 
nOfDg n base = 1 + floor (logBase base (n*n)) 

錯誤:

No instance for (Floating Int) 
    arising from a use of `logBase' at C:\haskel\dgnum.hs:4:24-38 
    Possible fix: add an instance declaration for (Floating Int) 
    In the first argument of `floor', namely `(logBase b (n * n))' 
    In the second argument of `(+)', namely `floor (logBase b (n * n))' 
    In the expression: 1 + floor (logBase b (n * n)) 

回答

10

logBase需要其實現浮動類型類兩個參數。在將參數傳遞給logBase之前,您需要從參數中調用參數。這編譯爲我6.10.3:

nOfDg :: Int -> Int-> Int 
nOfDg n base = 1 + floor (logBase (fromIntegral base) (fromIntegral (n*n))) 

你必須記住,Haskell是非常強類型的,所以你不能只是假設,提供給你的函數int參數將自動強制轉換爲浮點數日誌功能通常採用。

5

logBase被聲明爲在浮點類型上工作。 Int不是浮點類型,有no automatic conversion in Haskell。試試這個:

-- Number of digits needed for the multiplication table n*n in base 'base' 
nOfDg :: Int -> Float -> Int 
nOfDg n base = 1 + floor (logBase base (fromIntegral (n*n))) 
+0

我想你還需要'(fromIntegral base)'。 –

+0

@Jason:不是Dan提供這種功能的類型,你不會。 – Chuck

+0

是的,取決於你想如何使用它。要麼就像我擁有它,如果可以更改類型簽名,或者如果不是,則使用Andy的版本。 –

3

從前奏:

logBase :: Floating a => a -> a -> a 

這意味着使用logBase您必須使用浮動型。但int是不是一個浮點類型,並沒有對數字類型的自動轉換,因此你必須把它從int轉換爲浮動類型:

nOfDg n base = 1 + floor (logBase (toEnum base) (toEnum n)) 

的toEnum功能需要一個int參數,並返回「枚舉「類型。好的一面是,浮子枚舉的一個實例,所以你可以使用它

toEnum :: Enum a => Int -> a 

你應該讀/記錄您關於在Haskell數值類型(數字,分數,標準型類整型,浮點... ),因爲他們經常在代碼中彈出,學習轉換可能會有用。

編輯:這個Haskell Wiki Book提供了一個非常有用的標準類型類之間的關係圖,包括數字類型。