在接口 ( ) 中包含“智能构造函数”方法是一种优良传统class
:
class Collection c a where
empty :: c a
singleton :: a -> c a
-- etc
将它们作为模式同义词提供会很好:
{-# LANGUAGE PatternSynonyms #-}
instance Ord a => Collection [] a where
empty = []
singleton x = [x]
pattern PEmpty = []
pattern PSingleton x = [x]
但是您不能将 PatSyns 放在类中。我有一些工作,但它似乎有很多丑陋的代码。任何人都可以建议清理它的方法吗?(下面列出了具体的丑陋。)
{-# LANGUAGE ViewPatterns #-}
pattern PEmpty :: (Eq (c a), Collection c a) => c a
pattern PEmpty <- ((==) empty -> True) where
PEmpty = empty
pattern PSingleton :: (Ord a, Collection c a) => a -> c a
pattern PSingleton x <- (isSingleton -> Just x) where
PSingleton x = singleton x
-- needs an extra method in the class:
isSingleton :: c a -> Maybe a
-- instance ...
isSingleton [x] = Just x
isSingleton _ = Nothing
- 令人讨厌的是,这些必须是明确的双向模式;特别是因为 'under
where
' 行与实例重载如此直接可比。 - 对于
empty
模式,我必须引入一个明确的(==)
测试和支持Eq
约束——以实现简单的模式匹配。(我想我可以调用一个isEmpty
方法。) - 对于该
singleton
模式,我避免了显式(==)
测试,但需要在类中的方法上加倍。 - 我真的不喜欢
ViewPatterns
;我希望 PatSyns 可以提供一些方法来避免它们。