2010-12-06 115 views
2

我是新來的Haskell和我試圖實施一門功課的計算器。我停留在一個地方,我需要在兩個值進行分工,我認爲這個問題是,他們的類型不能被推斷或需要聲明/轉換。我正在努力學習如何自己解決這個問題,但沿途的任何見解都會有所幫助。haskell分割類型不匹配?

下面是代碼:

data Value e = OK e | Error String deriving (Eq) 

-- assuming we know how to type e can be shown, i.e. Show e, then 
-- we know how to show a Value e type 
instance (Show e) => Show (Value e) where 
    show (OK x) = (show x) 
    show (Error s) = "ERROR: " ++ s 

type Token = String 
type Result = Value Int 
type Intermediate = [ (Value Int) ] 

-- an algebra is a things that knows about plus and times 
class Algebra a where 
    plus :: a -> a -> a 
    times :: a -> a -> a 
    subtraction :: a -> a -> a 
    division :: a -> a-> a 

-- assuming that we know how to + and * things of type e, (i.e. 
-- we have Num e, then we have algebra's over Value e 
instance (Num e) => Algebra (Value e) where 
    plus (OK x) (OK y) = (OK (x+y)) 
    times (OK x) (OK y) = (OK (x*y)) 
    subtraction (OK x) (OK y) = (OK (x-y)) 
    division (OK x) (OK 0) = (Error "div by 0") 
    division (OK x) (OK y) = (OK (x `div` y)) <-- this is line 44 that it complains about 

這是當我嘗試運行該程序通過ghci的test.hs

test.hs:44:34: 
    Could not deduce (Integral e) 
     from the context (Algebra (Value e), Num e) 
     arising from a use of `div' at test.hs:44:34-42 
    Possible fix: 
     add (Integral e) to the context of the instance declaration 
    In the first argument of `OK', namely `(x `div` y)' 
    In the expression: (OK (x `div` y)) 
    In the definition of `division': 
     division (OK x) (OK y) = (OK (x `div` y)) 

有更多的代碼來這個錯誤,我想我會爲了清楚起見,請將其保留,但如果此處不清楚,我總是可以對其進行編輯。

+0

這不應該是一個問題.. – Omnipotent 2011-04-26 18:57:15

回答

8
div :: (Integral a) => a -> a -> a 
(/) :: (Fractional a) => a -> a -> a 

Num a並不意味着要麼Integral a也不Fractional a(雖然逆適用,當然)。如果你想使用div,你必須提供的東西至少限制性作爲Integral a上下文。

+0

...我不能相信我花了這麼長吧,我一直在尋找在錯誤的地方試圖限制在使用E型。你指出民領着我到`實例(民E)=>`可能的代碼的唯一行我沒有考慮在測試過程中不斷變化的...謝謝您 – 2010-12-06 01:10:42

3

div只適用於Integral值(標準Prelude中只有IntInteger)。 Float並與/操作Double支持分裂,但你的問題的根源在於Num類型類實際上並不要求使用任何類型的除法運算。

這很有道理 - 我們可能想要製作大量的數字集合,以便在乘法不可逆的情況下生成Num的實例 - 分割操作本質上沒有意義。