哈斯克尔的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)Pair是这些的一个实例:
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...would IMO也有实例。
是否没有足够的匹配类型?或者是关于我的代码的某些方面存在严重缺陷?
发布于 2012-11-27 00:24:45
范畴论中的单体是内函子,即当域和余域是同一范畴时的函子。但是Bifunctor是从产品类别Hask x Hask到Hask的函数器。但我们可以尝试找出Hask x Hask类别中的monad是什么样子的。这是一个类别,其中对象是成对的类型,即(a, b),箭头是成对的函数,即从(a, b)到(c, d)的箭头具有类型(a -> c, b -> d)。此类别中的内函数将类型对映射到类型对,即(a, b)到(l a b, r a b),并将箭头对映射到箭头对,即
(a -> c, b -> d) -> (l a b -> l c d, r a b -> r c d)如果将此映射函数拆分为2,您将看到Hask x Hask中的内函数器与两个Bifunctor相同,即l和r。
现在对于单体:return和join是箭头,所以在本例中都是两个函数。return是从(a, b)到(l a b, r a b)的箭头,join是从(l (l a b) (r a b), r (l a b) (r a b))到(l a b, r a b)的箭头。它看起来是这样的:
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 f m)类似,我们可以定义:
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)相对单子
最近,relative monads已经被开发出来。相对单体不需要是内部函数器!如果我们把论文翻译成Haskell中的Bifunctors,你会得到:
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它定义了一个相对于双函数器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的结果中提取这两个值。
https://stackoverflow.com/questions/13556314
复制相似问题