这件事与KleisliFunctor类似?

use*_*465 6 monads haskell typeclass category-theory

以下是我们如何定义KleisliFunctor:

class (Monad m, Functor f) => KleisliFunctor m f where
  kmap :: (a -> m b) -> f a -> f b
  kmap f = kjoin . fmap f

  kjoin :: f (m a) -> f a
  kjoin = kmap id
Run Code Online (Sandbox Code Playgroud)

这是类型类吗?

class (Functor f, Monad m) => Absorb f m where
  (>>~) :: f a -> (a -> m b) -> m b
  a >>~ f = ajoin $ fmap f a

  ajoin :: f (m a) -> m a
  ajoin a = a >>~ id
Run Code Online (Sandbox Code Playgroud)

适合类别理论吗?有什么法律?是吗

a >>~ g . f     === fmap f a >>~ g
a >>~ (f >=> g) === a >>~ f >>= g
Run Code Online (Sandbox Code Playgroud)

dup*_*ode 4

这是一个推测性的答案。谨慎行事。

我们首先考虑一下KleisliFunctor,重点关注类似绑定的箭头映射:

class (Monad m, Functor f) => KleisliFunctor m f where
  kmap :: (a -> m b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)

为了使其实际上成为从 Kleisli 类别mHask的函子,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
Run Code Online (Sandbox Code Playgroud)

事实上,涉及两个Functors 使事情有点不寻常,但并非不合理——例如,法律确实适用于,这是该帖子提到的mapMaybe第一个具体例子。KleisliFunctor

至于Absorb,为了清楚起见,我将翻转类似绑定的方法:

class (Functor f, Monad m) => Absorb f m where
  (~<<) :: (a -> m b) -> f a -> m b
Run Code Online (Sandbox Code Playgroud)

如果我们正在寻找类似于 的东西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)
Run Code Online (Sandbox Code Playgroud)

...我现在能想到的唯一合理的事情是拥有一个单子态射 asidAbsorb并在相反方向(即 from mto f)使用第二个单子态射,以便compAbsorb可以通过应用第一个函数然后返回来实现并f最终应用第二个函数。我们需要解决这个问题,看看我的假设是否合适,这种方法是否有效,以及它是否会产生对您的目的有用的东西。