Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 从程序员的范畴理论理解bifunctor-第8章_Haskell_Functional Programming_Category Theory_Type Constructor_Bifunctor - Fatal编程技术网

Haskell 从程序员的范畴理论理解bifunctor-第8章

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

我要去精神病院

在第8.3节中,Bartosz定义了这种类型

新型双组份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
    具有类型
    (a->a'->(b->b'->bfab->bfab'
    ;我认为这没有下面的有趣,因为它毕竟只是8.1中介绍的
    Bifunctor
    类型
    类的
    bimap
    的签名
  • 相反,左边的
    bimap
    是我们定义的在其第4和第5个参数中制作
    BiComp
    a
    Bifunctor
    ;参数
    f1
    f2
    是必须作用于类型实体的函数,类型实体是
    BiComp
    的第4和第5个参数;因此,此
    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编写
我仍然需要研究这部分语法(我在这里看到了很多问题),但在这种情况下它不是超级棒吗?如果不是,为什么?那么你的观点是作者确实在写rhs
bimap
,而不是lhs的类型?你实际上不需要所有的
部分;如果你省略它,它是隐含的。也就是说,我发现它非常清楚哪些类型变量是新的,哪些是继承的因此,在该签名中,
bf
不是
forall
的一部分,这意味着它实际上是固定的,而
forall
类型变量可以在调用函数时用任何你想要的东西实例化。是的,
bimap::(fu a->fu a')->……
类型是rhs,而不是lhs。