Haskell, Gen instance of B when class A provides enough info for class B

故事扮演 提交于 2019-12-01 23:08:12

The standard trick for this is to give implementations of the appropriate functions and let users write their own instances. For example, you might write

fmapColl :: (Collection c a, Collection c b) => (a -> b) -> c a -> c b
fmapColl f ca
    | emptyColl ca = mkEmptyColl -- you don't have this in your class, but probably should
    | otherwise = case splitColl ca of
        (a, ca') -> f a >|< fmapColl f ca'

Assuming we had a suitable type class, say, CFunctor:

class CFunctor f where
    type ConstraintI f
    type ConstraintO f
    cfmap :: (ConstraintI i, ConstraintO o) => (i -> o) -> f i -> f o

Then for a given Collection instance like Set we could instantiate CFunctor with minimal actual code like this:

instance CFunctor Set where
    type ConstraintI Set = Ord
    type ConstraintO Set = Ord
    cfmap = fmapColl

You can see this pattern -- defining a "default" implementation for users to put in their instances -- in the base library's fmapDefault, for example.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!