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有实例为好。
是否有没有足够的匹配类型? 或者是关于我的代码漏洞百出的东西吗?
在类别理论的单子是endofunctor,即仿函数,其中结构域和值域是同一种类。 但Bifunctor
是从产品类别仿函数Hask x Hask
到Hask
。 但是,我们可以尝试找出在一个单子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, l
和r
现在的单子: return
和join
是箭,所以在这种情况下,两者都是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
。