2016-10-24 22 views
0

こんにちは私はハスケルで新しく、問題があります。予想されるタイプdと実際のタイプbとを一致させることができません

私たちは、このコード持ってそうするPartidaためとPartidas(Facturas)のリストについては、有効な方法を作成したい:

data Bebida a b where { 
     Bebida::(Integral a, Fractional b)=>{codigo::a, nombre::[Char], precio::b } -> Bebida a b 
    } 

data Partida a b c where { 
    ParMult:: (Integral a, Integral c, Fractional b) => {cantidad::c, bebida::Bebida a b} -> Partida a b c; 
    ParUnit:: (Integral a, Integral c, Fractional b) => {bebida::Bebida a b} -> Partida a b c 
    } 

type Factura a b c = [Partida a b c] 

class Preciable a where 
precioe :: (Fractional d) => a -> d 

instance (Integral a, Fractional b, Integral c) => Preciable (Partida a b c) where 
precioe (ParMult n b) = (fromIntegral(n)*(precio b)) 
precioe (ParUnit b) = (precio b) 

instance (Integral a, Integral c, Fractional b, Eq b) => Preciable (Factura a b c) where 
precioe f = sum [precioe x | x<-f] 

私は知らないが、なぜ私にこれを与えています間違い。誰かが私に、なぜ、ハスケルがこのミスを私に伝えているのかを教えてもらえますか?

ありがとうございました!

+1

' precioe ::(フラクショナルD)=> A:は、あなたの書き込みrealToFracを使用してインスタンスをすることができます'precioe'。あなたの実装では、呼び出し側に自由に指定するのではなく、代わりに 'Partida'や' Factura'型に焼いた型を 'd'にする必要があります。 – amalloy

答えて

3

問題がprecioeでは、任意FractionaldDoubleRationalなど)を返すことになっています。 precioeの発信者は、それが何であるかを決定します。

あなたFractionalb)であるPreciableリターン何かのインスタンスが、必ずしもそうではないprecioeの呼び出し側が望んでいたFractionald)。また、高速化のためのルールを書き換えて使用してこれらの2を組み合わせた機能があります

class (Num a, Ord a) => Real a where 
    toRational :: a -> Rational 

:幸いfromRational :: Fractional d => Rational -> d

あなたはRealクラスを使用してbRationalに変えることができます使用して、任意のFractionaldを作成する方法があります特定のタイプ間のコンバージョン:

realToFrac :: (Real a, Fractional b) => a -> b 
realToFrac = fromRational . toRational 

の制約をに追加すると - のために働くことを約束D '> *コードによって選ばれたまったく* `D'、*呼び出し*

instance (Integral a, Real b) => Preciable (Partida a b c) where 
    precioe (ParMult n b) = fromIntegral n * realToFrac (precio b) 
    precioe (ParUnit b) = realToFrac (precio b) 

instance (Integral a, Real b) => Preciable (Factura a b c) where 
    precioe f = sum [precioe x | x <- f] 
関連する問題