Biapplicative和Bimonad?(Biapplicative and Bimonad?)

2019-07-04 02:39发布

Haskell的Data.Bifunctor基本上是:

class Bifunctor f where
  bimap :: (a -> c) -> (b -> d) -> f a b -> f c d 

我能找到一个Biapply为好。 我的问题是,为什么没有一个完整的双层次(bierarchy?),如:

class Bifunctor f => Biapplicative f where
  bipure :: a -> b -> f a b
  biap :: f (a -> b) (c -> d) -> f a c -> f b d 

class Biapplicative m => Bimonad m where
  bibind :: m a b -> (a -> b -> m c d) -> m c d

  bireturn :: a -> b -> m a b
  bireturn = bipure

bilift :: Biapplicative f => (a -> b) -> (c -> d) -> f a c -> f b d
bilift f g = biap $ bipure f g 

bilift2 :: Biapplicative f => (a -> b -> c) -> (x -> y -> z) -> f a x -> f b y -> f c z
bilift2 f g = biap . biap (bipure f g)

对是这些实例:

instance Bifunctor (,) where
  bimap f g (x,y) = (f x, g y)

instance Biapplicative (,) where
  bipure x y = (x,y)
  biap (f,g) (x,y) = (f x, g y)

instance Bimonad (,) where
  bibind (x,y) f = f x y

和类型喜欢...

data Maybe2 a b = Fst a | Snd b | None
--or 
data Or a b = Both a b | This a | That b | Nope

......将IMO有实例为好。

是否有没有足够的匹配类型? 或者是关于我的代码漏洞百出的东西吗?

Answer 1:

在类别理论的单子是endofunctor,即仿函数,其中结构域和值域是同一种类。 但Bifunctor是从产品类别仿函数Hask x HaskHask 。 但是,我们可以尝试找出在一个单子Hask x Hask类别的模样。 它是一类,其中的对象是对类型,即(a, b)和箭头是双功能的,即,从箭头(a, b)(c, d)具有类型(a -> c, b -> d) 此类别中的endofunctor映射对类型对类型,即(a, b)(lab, rab)和双箭头来对箭头所示,即

(a -> c, b -> d) -> (l a b -> l c d, r a b -> r c d)

如果您在2拆分此地图功能,你会看到,在一个endofunctor Hask x Hask是相同的两个Bifunctor S, lr

现在的单子: returnjoin是箭,所以在这种情况下,两者都是2层的功能。 return是从箭头(a, b)(lab, rab)join是从箭头(l (lab) (rab), r (lab) (rab))(lab, rab) 这是什么样子:

class (Bifunctor l, Bifunctor r) => Bimonad l r where
  bireturn :: (a -> l a b, b -> r a b)
  bijoin :: (l (l a b) (r a b) -> l a b, r (l a b) (r a b) -> r a b)

或分离出来:

class (Bifunctor l, Bifunctor r) => Bimonad l r where
  bireturnl :: a -> l a b
  bireturnr :: b -> r a b
  bijoinl :: l (l a b) (r a b) -> l a b
  bijoinr :: r (l a b) (r a b) -> r a b

而类似于m >>= f = join (fmap fm)我们可以定义:

  bibindl :: l a b -> (a -> l c d) -> (b -> r c d) -> l c d
  bibindl lab l r = bijoinl (bimap l r lab)
  bibindr :: r a b -> (a -> l c d) -> (b -> r c d) -> r c d
  bibindr rab l r = bijoinr (bimap l r rab)

相对单子

近日, 相对单子已经制定出来。 的相对单子并不需要是一个endofunctor! 如果我们从纸张到翻译Bifunctor S IN Haskell中,您可以:

class RelativeBimonad j m where
  bireturn :: j a b -> m a b
  bibind :: m a b -> (j a b -> m c d) -> m c d

它定义了一个单子相对bifunctor j 。 如果你选择j(,)你会得到你的定义。

法律是一样的单子规律:

bireturn jab `bibind` k = k jab
m `bibind` bireturn = m
m `bibind` (\jab -> k jab `bibind` h) = (m `bibind` k) `bibind` h

第一定律防止Maybe2被一个实例,因为bibind必须能够从结果中提取两个值bireturn



文章来源: Biapplicative and Bimonad?