まず、同じ関数の異なる方程式に異なる型シグネチャを与えることはまったく不可能です。どの関数も、方程式の数に関係なく、1 つの型しか持てません。
第二に、負の制約は Haskell では適切な意味を持ちません (持たないでしょう)。クラス制約の意味を思い出してください。
f :: Num a => a -> a -> a
f x y = x + y
Num atype ofは、型 classfの任意のクラス メソッドをNumtype の値に適用できることを意味しますa。一般的な動作を得るために、意識的に具象型に名前を付けていません。本質的に、私たちは「正確に何であるかは気にしませんが、操作がそれに適用できることaは知っています」と言っています。Numしたがって、Numメソッド onxおよびを使用できますyが、それ以上は使用できません。つまり、メソッド onおよび以外は何も使用できません。これが型クラス制約とは何か、なぜ必要なのかです。関数の汎用インターフェイスを指定しています。Numxy
ここで、架空のnot Num a制約を考えてみましょう。この声明はどのような情報をもたらしますか? aそれが であってはならないことはわかっていますNum。しかし、この情報は私たちにとってまったく役に立ちません。検討:
f :: not Num a => a -> a
f = ???
の代わりに何を置けます???か? 明らかに、私たちは配置できないものを知っています。ただし、この署名にはそれ以上の情報がないことを除いて
f :: a -> a
唯一の操作は次のfとおりですid(まあ、undefinedそれも可能ですが、それは別の話です)。
最後にあなたの例を考えてみましょう:
showSquare :: (Show a, not Num a) => a -> String
showSquare x = "I don't know how to square " ++ (show x)
私はあなたの例の最初の部分を意図的に与えていません。私の答えの最初の文を見てください。異なるタイプの異なる方程式を持つことはできません。しかし、この機能だけではまったく役に立ちません。ここで制約を安全に削除できますがnot Num a、何も変更されません。
Int静的に型付けされた Haskell でのこのような負の制約の唯一の使用法は、たとえばfor not Num a-constrainted 変数を指定したときにコンパイル時エラーを生成することです。しかし、これには何の役にも立ちません。