【发布时间】:2011-08-15 03:44:43
【问题描述】:
我有一个代数数据类型,其中一些构造函数具有可比较的值,而一些构造函数则不具有。我编写了一些比较函数,它们的工作方式类似于标准的 (==) 和 (/=) 运算符,但对于没有意义的比较返回 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 显然不能在helper 的定义中同时绑定到Int 和Float; GHC 将其绑定到Float,然后在处理IntValue 的行上抱怨类型不匹配。
像(==) 这样的函数在直接使用时是多态的;有没有办法将它传递给另一个函数并让它保持多态?
【问题讨论】:
标签: haskell types polymorphism higher-order-functions