2011-11-16 66 views
2

Haskell - 如何简单地在实例中使“div”或“/”?

data SomeData = Number Integer | String String | Bool Bool 
        deriving Eq 

而且,我想用 'DIV' 与SomeData。

instance Num SomeData where 
      (Number x) + (Number y) = Number $ x + y -- It's Ok. 
      (Number x) - (Number y) = Number $ x - y -- It's Ok. 
      (Number x) * (Number y) = Number $ x * y -- It's ok. 
    instance Integral SomeData Where 
      (Number x) `div` (Number y) = Number $ x `div` y 

但我得到了错误消息。

main.hs:105:10: 
    No instance for (Real SomeData) 
     arising from the superclasses of an instance declaration 
    Possible fix: add an instance declaration for (Real SomeData) 
    In the instance declaration for `Integral SomeData' 

main.hs:105:10: 
    No instance for (Enum SomeData) 
     arising from the superclasses of an instance declaration 
    Possible fix: add an instance declaration for (Enum SomeData) 
    In the instance declaration for `Integral SomeData' 

好吧,如果我想使用div与SomeData数据,应该我写Real InstanceEnum Instance为SomeData一步一步?还是有另一种好方法?

+0

是不是div的问题,返回一个真正的,你没有一个类型构造函数的SomeData数字真实? – Paolo

+0

@Paolo No.' div :: Integral a - > a - > a - > a'。 – fuz

回答

2

是的,您需要编写实例RealEnum。你可以通过做作弊

instance Real SomeData 
instance Enum SomeData 

然后,如果你使用这些类中的方法,你将会遇到运行时失败。 或者,Real

instance Real SomeData where 
    toRational (Number i) = toRational i 

(你有很多的已经部分功能,所以我假设你不介意多一些。)

2

解决的问题,如这是使用的一般方法:info命令ghci

Prelude> :i Integral 
class (Real a, Enum a) => Integral a where 
    quot :: a -> a -> a 
    rem :: a -> a -> a 
    div :: a -> a -> a 
    mod :: a -> a -> a 
    quotRem :: a -> a -> (a, a) 
    divMod :: a -> a -> (a, a) 
    toInteger :: a -> Integer 

所以,不,你不能执行Integral没有实施Real。你可以从div直开始:

Prelude> :i div 
class (Real a, Enum a) => Integral a where 
    ... 
    div :: a -> a -> a 
    ... 
     -- Defined in GHC.Real 
infixl 7 div 

所以你可以看到,div是体型类的方法,你需要RealEnum被定义为好。如果你检查Real,它需要NumOrd