2015-11-09 47 views
1

我正在嘗試編寫一個簡單的函數來刪除數字的最後一位數字,並返回數字的其餘部分。Haskell中的瑣碎數字轉換問題

dropLastDigit :: (Integral b) => b -> b 
dropLastDigit x = (quot x 10) * (floor $ logBase 10 x) 

然而,當我嘗試這個加載到ghci中,我得到:

Could not deduce (Floating b) arising from a use of ‘logBase’ 
    from the context (Integral b) 
     bound by the type signature for 
       dropLastDigit :: Integral b => b -> b 
     at haskelljokes.hs:6:18-39 
    Possible fix: 
     add (Floating b) to the context of 
     the type signature for dropLastDigit :: Integral b => b -> b 
    In the second argument of ‘($)’, namely ‘logBase 10 x’ 
    In the expression: floor $ logBase 10 x 
    In an equation for ‘dropLastDigit’: 
     dropLastDigit x = floor $ logBase 10 x 

然而,在ghci中運行此代碼:

:t (quot 101 10) * (floor $ logBase 10 101)

生產:(quot 101 10) * (floor $ logBase 10 101) :: Integral a => a

我的問題是,我做錯了什麼?爲什麼(相同的代碼?)在ghci中工作?

回答

3

它不一樣。您可以輕鬆地檢查:

ghci> let value101 = 101 :: Integral b => b 
ghci> let value10 = 10 :: Integral b => b 
ghci> (quot value101 value10) * (floor $ logBase value10 value101) 

<interactive>:7:28: 
    Could not deduce (RealFrac s0) arising from a use of `floor' 
    from the context (Integral a) 
     bound by the inferred type of it :: Integral a => a 
     at <interactive>:7:1-60 
    The type variable `s0' is ambiguous 
    Note: there are several potential instances: 
     instance RealFrac Double -- Defined in `GHC.Float' 
     instance RealFrac Float -- Defined in `GHC.Float' 
     instance Integral a => RealFrac (GHC.Real.Ratio a) 
     -- Defined in `GHC.Real' 
    In the expression: floor 
    In the second argument of `(*)', namely 
     `(floor $ logBase value10 value101)' 
    In the expression: 
     (quot value101 value10) * (floor $ logBase value10 value101) 

-- even more... 

的問題是,無論10101有型Num a => a,無論在哪裏使用它們。因此logBase 10 101使用它們與默認Fractional實例(Double),而quot使用它們與默認Integral實例。

這就是說,你的功能不會「刪除」最後一位數字。如果你只是想變換123451234,您可以簡化dropLastDigit

dropLastDigit x = x `div` 10 

如果,但是,想要改造1234512340,你只是必須在10點以後乘:

dropLastDigit x = 10 * (x `div` 10) 
4

你的函數改爲

dropLastDigit :: (Integral b) => b -> b 
dropLastDigit x = (quot x 10) * (floor $ logBase 10 (fromIntegral x)) 

您已經進入了ghci中運行的代碼是不相同的。您已將x替換爲101。您的功能中的x已註冊(按類型簽名)爲b類型b類別Integral類,但logBase類需要Floating類中的某些內容。

另一方面,字面101的類型爲Num a => a,即它被重載並且可以用於任何數字類型。因此,GHCi可以在Integer類型的第一次出現時使用它,作爲quot的參數,並在第二次出現時作爲Double作爲logBase的參數。

+0

謝謝你明確的迴應。真的有助於提醒我思考我的類型類。 Upvoted。澤塔擊敗你,所以他得到了接受。 –