这是一个推测性的答案。谨慎行事。
我们首先考虑KleisliFunctor
,重点关注类似绑定的箭头映射:
class (Monad m, Functor f) => KleisliFunctor m f where
kmap :: (a -> m b) -> f a -> f b
因为这实际上是来自 Kleisli 范畴的函子m
to Hask, kmap
必须遵循相关函子定律:
-- Mapping the identity gives identity (in the other category).
kmap return = id
-- Mapping a composed arrow gives a composed arrow (in the other category).
kmap (g <=< f) = kmap g . kmap f
事实是有两个Functor
涉及的事情让事情有点不寻常,但并非不合理——例如,法律确实适用mapMaybe
,这是第一个具体例子KleisliFunctor
帖子提到。
As for Absorb
,为了清楚起见,我将翻转类似绑定的方法:
class (Functor f, Monad m) => Absorb f m where
(~<<) :: (a -> m b) -> f a -> m b
如果我们正在寻找类似的东西KleisliFunctor
,立即出现的一个问题是哪个类别将具有类型的函数f a -> m b
作为箭头。肯定不可能是Hask,作为其身份(类型f a -> m a
) 不可能是id
。我们不仅要弄清楚身份,还要弄清楚组成。对于一些并非完全不同的东西Monad
...
idAbsorb :: f a -> m a
compAbsorb :: (f b -> m c) -> (f a -> m b) -> (f a -> m c)
...我现在能想到的唯一合理的事情就是单子态射为idAbsorb
并在相反的方向上使用第二个单子态射(即从m
to f
) 以便compAbsorb
可以通过应用第一个函数,然后返回到来实现f
最后应用第二个函数。我们需要解决这个问题,看看我的假设是否合适,这种方法是否有效,以及它是否会产生对您的目的有用的东西。