Haskell 从程序员的范畴理论理解bifunctor-第8章
我要去精神病院 在第8.3节中,Bartosz定义了这种类型Haskell 从程序员的范畴理论理解bifunctor-第8章,haskell,functional-programming,category-theory,type-constructor,bifunctor,Haskell,Functional Programming,Category Theory,Type Constructor,Bifunctor,我要去精神病院 在第8.3节中,Bartosz定义了这种类型 新型双组份bf fu gu a b=双组份(bf(fu a)(gu b)) 在这里,如果我理解一点Haskell,bf,fu,和gu是类型构造函数,bf(*->*)->(*->*)->(*->*)->*->*->*,以及fu和gu*(就像可能或[]]),而,和b是一般类型的*BiComp是一种很难写的类型构造函数,而右边的BiComp是一种值构造函数,所以它的类型是(bf(fu a)(gu b))->BiComp bf fu gu
新型双组份bf fu gu a b=双组份(bf(fu a)(gu b))
在这里,如果我理解一点Haskell,bf
,fu
,和gu
是类型构造函数,bf
(*->*)->(*->*)->(*->*)->*->*->*,以及fu
和gu
*(就像可能
或[]]
),而,和b
是一般类型的*
<左边的code>BiComp
是一种很难写的类型构造函数,而右边的BiComp
是一种值构造函数,所以它的类型是(bf(fu a)(gu b))->BiComp bf fu gu a b
然后,作者在a
和b
中创建了BiComp
双函数,前提是类型构造函数参数bf
也是一个bifunctor
,并且类型构造函数fu
和gu
是Functor
s:
instance(Bifunctor bf,Functor fu,Functor gu)=>Bifunctor(BiComp bf fu gu)其中
bimap f1 f2(BiComp x)=BiComp((bimap(fmap f1)(fmap f2))x)
到目前为止一切都很好,在这一点上我觉得一切都是合理的。除了对类型构造函数和值构造函数使用相同的名称可能会让我迷路
现在,我想做以下观察:
- 定义右侧的
是利用约束的一个:它是bimap
,被假定为任何类型的构造函数bimap
的bf
实例中定义的,因此这个Bifunctor
具有类型bimap
;我认为这没有下面的有趣,因为它毕竟只是8.1中介绍的(a->a'->(b->b'->bfab->bfab'
类型Bifunctor
类的
的签名李>bimap
- 相反,左边的
是我们定义的在其第4和第5个参数中制作bimap
aBiComp
;参数Bifunctor
和f1
是必须作用于类型实体的函数,类型实体是f2
的第4和第5个参数;因此,此BiComp
的类型为bimap
(a->a')->(b->b')->双组高炉富谷a b->双组高炉富谷a'b'
- 相反,左边的
bimap::(fua->fua')->(gub->gub')->bf(fua)(gub)->bf(fua')(gub'))
因为这是右边的bimap
类型,我在上面的要点中写的,除了它是用a
=fu a
,a'
=fu a'
,等等写的
我是不是错过了什么(或者想得太多了…?你很接近了
首先,您的bf
类型有误。它实际上只是*->*->*
,这正是我们所期望的,因为它将是一个Bifunctor
。当然,BiComp
的那种非常疯狂:
BiComp::(*->*->*)->(*->*)->(*->*)->(*->*)->*)->*->*->*->->*->->*
至于要点中的类型,从技术上讲,它们都是正确的,但是使用新的类型变量(特别是对于第一个要点中的类型!)可能会有助于使这一切更加清晰。事实上,右侧的bimap
具有
bimap::对于所有c'd'。(c->c')->(d->d')->bf c d->bf c'd'
我们需要使用它来制作一些东西,将输入值类型bf(fu a)(gu b)
转换为输出值类型bf(fu a')(gu b')
。只有让c~fu a,c'~fu a',d~gu b,d'~gu b'
,我们才能这样做。让我们来看看这对我们的RHS<代码> BIMAP < /C> >:
bimap::(fua->fua')->(gub->gub')->bf(fua)(gub)->bf(fua')(gub'))
啊哈!那正是你在右手边发现的!而且,我们可以准确地提供我们需要的论据。首先,类型为
fua->fua'
的函数。我们有一个给定的函数f1::a->a'
,我们知道fu
是一个函子,所以我们可以用fmap f1
得到我们需要的函数。同样地,对于f2
和fmap f2
,一切都很顺利。哦,现在我明白了我的胡子:我写的那种是部分应用的类型构造函数,BiComp bf
。你为什么要为所有c'd编写。
我仍然需要研究这部分语法(我在这里看到了很多问题),但在这种情况下它不是超级棒吗?如果不是,为什么?那么你的观点是作者确实在写rhsbimap
,而不是lhs的类型?你实际上不需要所有的部分;如果你省略它,它是隐含的。也就是说,我发现它非常清楚哪些类型变量是新的,哪些是继承的因此,在该签名中,bf
不是forall
的一部分,这意味着它实际上是固定的,而forall
类型变量可以在调用函数时用任何你想要的东西实例化。是的,bimap::(fu a->fu a')->……
类型是rhs,而不是lhs。