1

さまざまな数値タイプを比較するために、以下のコードをどのように機能させるのですか?

foo::(Num a) => (Num b) => a -> b -> Bool
foo a b = (a == b)

コンテキスト(Num a、Num b)から(a〜b)を推測することについてエラーが発生します

4

2 に答える 2

8

まず、型注釈が構文的に間違っています(GHCはそれを受け入れますが、レポートの文脈自由構文を読んだことによると)、

foo::(Num a, Num b) => a -> b -> Bool

質問に関しては、それを行うことはできません。(<)タイプOrd a => a -> a -> Boolはです。したがって、両方の引数は同じタイプである必要があります。

単なる制限よりも強い制限がある場合Num、たとえば、

bar :: (Real a, Real b) => a -> b -> Bool
bar a b = toRational a < toRational b

値を比較するには、両方の引数を同じターゲットタイプに(意味のある変換で)変換できる必要があります。Realクラス内の型に対して、共通のターゲット型へのそのような変換を提供します(開始型が浮動小数点型の場合、NaNおよび無限大では合理的に機能しないtoRationalという警告があります)。制約についても同じことを達成します。toRationaltoIntegerIntegral

Num制約だけで利用できるそのような一般的なターゲットタイプはありません。

特別なニーズに応じて、ターゲットタイプを選択し、

class Convertible a where
    toTarget :: a -> Target

実行可能な制約であるかどうRealか。Integral

于 2012-10-07T00:57:19.793 に答える
4

これは不可能なはずNumです-すべてがまったく比較できるわけではないので-あなたが持っているとさえ言ってください

foo :: Num a => a -> b -> Bool
foo x y = x < y

そして、それを複素数に使用します。どのような概念<を使用しますか?辞書式順序は1つのオプションですが、それが理にかなっていることは明らかではありません。

2つの異なる数値タイプがある場合は、「複素数と実数をどのように比較しますか?または、Numモジュロ計算を使用してインスタンス化できる時間と分を比較しますか?」とお返しします。

Real a制約として使用した場合、toRational関数があります。これは、比較可能性の問題を解決する1つの方法です。

foo :: (Real a, Real b) => a -> b -> Bool
foo x y = x' < y'
        where x' = toRational x
              y' = toRational y
于 2012-10-07T00:57:41.393 に答える