さまざまな数値タイプを比較するために、以下のコードをどのように機能させるのですか?
foo::(Num a) => (Num b) => a -> b -> Bool
foo a b = (a == b)
コンテキスト(Num a、Num b)から(a〜b)を推測することについてエラーが発生します
さまざまな数値タイプを比較するために、以下のコードをどのように機能させるのですか?
foo::(Num a) => (Num b) => a -> b -> Bool
foo a b = (a == b)
コンテキスト(Num a、Num b)から(a〜b)を推測することについてエラーが発生します
まず、型注釈が構文的に間違っています(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
という警告があります)。制約についても同じことを達成します。toRational
toInteger
Integral
Num
制約だけで利用できるそのような一般的なターゲットタイプはありません。
特別なニーズに応じて、ターゲットタイプを選択し、
class Convertible a where
toTarget :: a -> Target
実行可能な制約であるかどうReal
か。Integral
これは不可能なはず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