2016-07-20 104 views
1

我想獲得的來自多個數字列表匹配,這裏是我的代碼:麻煩類型在Haskell

digits x = if x > 0 then (i : digits (floor (x/10))) else [i] 
    where i = (mod x 10) 

我得到這個代碼的錯誤是:

No instance for (Integral a0) arising from a use of ‘it’ 
    The type variable ‘a0’ is ambiguous 
    Note: there are several potential instances: 
     instance Integral Integer -- Defined in ‘GHC.Real’ 
     instance Integral Int -- Defined in ‘GHC.Real’ 
     instance Integral Word -- Defined in ‘GHC.Real’ 
    In the first argument of ‘print’, namely ‘it’ 
    In a stmt of an interactive GHCi command: print it 

我做錯了什麼?

+0

使用'div'而不是'/'和'floor' – Carsten

+0

''digits x = if x> 0 then(x'mod'10):digits(x' div'10)else [x'mod'10 ] - 請注意,你會得到一個反向列表(在大多數情況下會有一個不想要的'0') – Carsten

+1

這是在某些情況下嘗試使用該函數的GHCi錯誤消息。總是爲你的函數添加類型簽名,這樣問題就會立即顯現,而不是其他地方。 – leftaroundabout

回答

2

要在卡斯滕的評論闡述,問題是,哈斯克爾推斷類型簽名

digits :: (RealFrac a, Integral a) => a -> [a] 

當你想要的是

digits :: Integral a => a -> [a] 

它推斷前者的原因是,您使用(/)floor,它們在FractionalRealFrac類中定義。正如左邊所指出的,在你嘗試用實際的數字運行你的函數之前,這不是一個真正的問題,在這一點上,Haskell無法找到一個好的數字類型來默認(Haskell數字文字實際上是多態的,並且有特殊的當你沒有明確地聲明一個類型時,默認的規則),因此奇怪的錯誤信息。如果你試圖像digits (1 :: Int)你會得到一個更具描述性錯誤消息:

<interactive>:19:1: error: 
    • No instance for (RealFrac Int) arising from a use of ‘digits’ 
    • In the expression: digits (1 :: Int) 
    In an equation for ‘it’: it = digits (1 :: Int) 

的修復,如卡斯滕指出的那樣,是用div而不是(/)floor

+0

謝謝你的詳細解釋 –

+1

好的答案 - 我想我們應該在Haskell-tag或者(beta?)文檔中包含這樣的東西,StackExchange正在處理這個問題/問題(使用'(/ ''需要'div')在這裏確實是一個常見問題 - 遺憾的是我找不到其他鏈接之一(通常標題並不直接表示問題) – Carsten

+0

@Carsten您會推薦將它放在哪裏在那裏?我戳了一下,但我真的找不到這種東西的地方... – Alec