у меня есть алгебраический тип данных с некоторыми конструкторами, которые держат сопоставимые значения и некоторых конструкторов, которые не делают. Я записал некоторые функции сравнения, которые работают как стандарт (==)
и (/=)
операторы, но возврат Ничто
для сравнений, которые не имеют смысла:
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
, Который работает, но повторение является громоздким — тем более, что у меня на самом деле есть больше Вариант
конструкторы и больше функций сравнения.
я думал, что мог факторизовать повторение в функцию помощника, это параметризовано на функции сравнения:
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 (/=)
, но это не работает, потому что переменная типа
, по-видимому, не может связать и с Интервал
и с Плавание
одновременно в определении помощник
; GHC связывает его с Плавание
и затем жалуется на несоответствие типов на строке, которая обрабатывает IntValue
.
функция А как (==)
является полиморфным при прямом использовании; существует ли способ передать, это к другой функции и иметь его остается полиморфным?