同等の値を保持するコンストラクターと保持しないコンストラクターを持つ代数的データ型があります。(==)
標準や(/=)
演算子のように機能するいくつかの比較関数をNothing
作成しましたが、意味をなさない比較に戻ります。
data Variant = IntValue Int
| FloatValue Float
| NoValue
equal :: Variant -> Variant -> Maybe Bool
equal (IntValue a) (IntValue b) = Just (a == b)
equal (FloatValue a) (FloatValue b) = Just (a == b)
equal _ _ = Nothing
unequal :: Variant -> Variant -> Maybe Bool
unequal (IntValue a) (IntValue b) = Just (a /= b)
unequal (FloatValue a) (FloatValue b) = Just (a /= b)
unequal _ _ = Nothing
それは機能しますが、繰り返しは扱いにくいです。特に、実際にはVariant
コンストラクターと比較関数が多いためです。
比較関数でパラメーター化されたヘルパー関数に繰り返しを因数分解できると思いました。
helper :: (Eq a) => (a -> a -> Bool) -> Variant -> Variant -> Maybe Bool
helper f (IntValue a) (IntValue b) = Just (f a b)
helper f (FloatValue a) (FloatValue b) = Just (f a b)
helper _ _ _ = Nothing
equal' :: Variant -> Variant -> Maybe Bool
equal' = helper (==)
unequal' :: Variant -> Variant -> Maybe Bool
unequal' = helper (/=)
しかし、型変数は明らかに両方にa
バインドできず、同時に;の定義にバインドできないため、これは機能しません。GHCはそれをにバインドし、を処理する行の型の不一致について文句を言います。Int
Float
helper
Float
IntValue
のような関数(==)
は、直接使用すると多形になります。それを別の関数に渡して多形のままにする方法はありますか?