How to add a class constraint to a Functor instance declaration in Haskell?

不羁岁月 提交于 2019-12-04 07:42:40

Sadly, you can't do that—Functor instances must accept any kind of mapping function without restriction.

You can kind of fake it, though.

newtype PF a = PF { unPF :: forall r . Eq r => (a -> r) -> Probability r }

instance Functor PF where
  fmap f (PF p) = PF (\mp -> p (mp . f))

Here, all of the functions that would be mapped over Probability have been "deferred" by PF. We run them all at once by "lowering" back into Probability when possible

lowerPF :: Eq a => PF a -> Probability a
lowerPF pf = unPF pf id

And in order to convert a Probability into a fmappable PF we must "lift" it

liftPF :: Probability a -> PF a
liftPF p = PF $ \mp -> PD (collect $ map (first mp) (mass p))
Dominique Devriese

What you're writing is not a Functor. A Functor's fmap must support arbitrary value types being mapped, not just those that satisfy a certain constraint. You can make it an instance of a more general concept though. For example, the package constrained-categories defines a class of constrained functors.

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