是否存在投标分配?我需要什么功能?

Kei*_*son 6 math haskell category-theory bifunctor distributive

我有代码(实际上是在C#中,但是这个问题与C#没有任何关系,所以我会谈到我在Haskell中说的所有类型)我在里面工作Either a b.然后我bind有一个带有签名的函数,在Haskell中说的是b -> (c, d),之后我想拉到c外面并在左边的情况下默认它,即我想要的(c, Either a d).现在这种模式多次出现在我写的一个特定服务中,所以我提出了一种方法来实现它.然而,每当我在没有理解正确的理论基础的情况下"弥补"这样的方法时,它就会让我感到困扰.换句话说,我们在这里处理什么抽象?

在一些F#代码中我遇到了类似的情况,其中我和我的对方都被颠倒了:(a, b) -> (b -> Either c d) -> Either c (a, d).我问朋友什么,这是他使我对穿越这使得即使我不得不在F#惊人,单态实现我很开心,由于缺乏类型类.(我希望我可以将我F1的Visual Studio 重新映射到Hackage;它是我编写.NET代码的主要资源之一).但问题是遍历是:

class (Functor t, Foldable t) => Traversable t where
    traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
Run Code Online (Sandbox Code Playgroud)

这意味着当你开始有一对,并希望"绑定"的要么是它的伟大工程,但不工作,当你开始用,因为对是不是一个非此即彼,并希望有一对就结了,应用型.

然而,我更多地考虑了我的第一个案例,那个不是traverse,并且意识到" c在左案例中违约"只能通过左侧案例的映射来完成,这会将问题改为具有这种形状:Either (c, a) (c, d) -> (c, Either a d)我认为是我们在算术中用乘法和加法看到的模式:a(b + c) = ab + ac.我还记得布尔代数和集合论中存在相同的模式(如果内存服务A intersect (B union C) = (A intersect B) union (A intersect C)).显然,这里有一些抽象的代数结构.但是,内存不起作用,我不记得它被称为什么.维基百科上的一点点快速解决了这个问题:这些是分配法则.快乐,快乐,Kmett给了我们分发:

class Functor g => Distributive g where
    distribute :: Functor f => f (g a) -> g (f a)
Run Code Online (Sandbox Code Playgroud)

它甚至有一个cotraverse因为它是双重的Travsersable!可爱!!但是,我注意到没有(,)实例.哦,哦.因为,是的,"默认c值"在哪里?然后我意识到,呃,我可能需要一个基于bifunctor的双向分配?也许是双重可怜的?概念:

class Bifunctor g => Bidistributive g where
    bidistribute :: Bifunctor f => f (g a b) (g a c) -> g a (f b c)
Run Code Online (Sandbox Code Playgroud)

这似乎是我所说的分配法的结构.我在Haskell中找不到这样的东西,因为我实际上在编写C#,这本身对我来说无关紧要.然而,对我来说重要的是不要提出虚假的抽象,并且尽可能地在我的代码中识别出合法的抽象,无论它们是否表达,都是为了我自己的理解.

我目前.InsideOut(<default>)在我的C#代码中有一个函数(扩展方法)(什么是hack,对吧!).我是否完全偏离基础来创建一个(是的,可悲的单形).Bidistribute(...)函数(扩展方法)来替换它并在调用它之前将左边的"默认"映射到左边的情况(或者只是识别"bidistributive"字符"由内而外")?

lef*_*out 6

bidistribute不能这样实施.考虑一些简单的例子

data Biconst c a b = Biconst c

instance Bifunctor (Biconst c) where
  bimap _ _ (Biconst c) = Biconst c
Run Code Online (Sandbox Code Playgroud)

然后我们就有了专业化

bidistribute :: Biconst () (Void, ()) (Void, ()) -> (Void, Biconst () () ())
bidistribute (Biconst ()) = ( ????, Biconst () )
Run Code Online (Sandbox Code Playgroud)

显然没有办法填补差距,这需要有类型Void.

实际上,我认为你真的需要Either那里(或者同形的东西),而不是任意的bifunctor.那么你的功能就是

uncozipL :: Functor f => Either (f a) (f b) -> f (Either a b)
uncozipL (Left l) = Left <$> l
uncozipL (Right r) = Right <$> l
Run Code Online (Sandbox Code Playgroud)

它的定义adjunctions(使用Hoogle找到).

  • @KeithPinson它是具有初始对象的任何类别的限制. (5认同)
  • 这是一种表达方式。虽然这并不意味着它“不是绝对的”。它仍然非常通用,只是特定于联积二元函子。 (2认同)