2010-12-06 73 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的实例 - 分割操作本质上没有意义。