2010-12-06 15 views
2

私はハスケルを新しくしており、私は宿題のための電卓を実装しようとしています。私は2つの値で除算を行う必要がある場所に立ち往生しています。そのタイプは推論できない、または宣言/変換する必要があると考えています。私はこれを自分自身で解決する方法を学ぼうとしていますが、道に沿った洞察は役に立つでしょう。ここでhaskell division type mismatch?

はコードです:ここでは

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

答えて

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

Num a(逆はもちろん、適用されますが)Integral aFractional aのいずれかを意味するものではありません。 divを使用する場合は、少なくともIntegral aコンテキストと同じように制限する必要があります。

+0

...私はこれに長い時間を費やしたとは思えませんが、eが使われているタイプを制限しようとしている間違った場所を探していました。 Numを指摘すると、私は 'instance(Num e)=>'おそらく、私がテスト中に変更を考慮していなかった唯一のコード行になりました...ありがとう –

3

divは、Integral値(標準プレリュードのIntまたはIntegerのみ)で動作します。 FloatおよびDouble/演算子で除算をサポートしていますが、問題の根本はNumというタイプキャストは実際にはどのような除算演算も要求していないということです。

これは意味があります。Numのインスタンスを作成したいと思うかもしれない数のコレクションがあります。乗算は不可逆的です。除算操作は本質的に無意味です。