我正在通过Haskell学习Swift中的函数式编程,并遇到了这个有趣的Transducers概念。一个代码示例实现了一个mapping
函数,它基本上会传出一个传感器,因为我们将转换规则作为参数传递。
受到启发,我很快将其转换为Swift等效物,这就是我所得到的:
func mapping < A, B, C> (f: A -> B) -> ( ( (C,B) -> C) -> ( (C,A) -> C) ) {
return { r in
return { result, a in
return r(result,f(a))
}
}
}
现在我的问题是注意转换函数如何从A到B((A -> B)
),但是换能器从B变为A(( (C,B) -> C) -> ( (C,A) -> C)
)?这是为什么?我确信这不是巧合,因为这个顺序很重要。哈斯克尔的专家,有谁?
答案 0 :(得分:4)
查看f
实际发生的呼叫。它正在将A
转换为B
,结果将用作r
的参数。因此r
必须期待B
;我们使用A -> B
函数预处理(C, B) -> C
函数的输入,从而产生(C, A) -> C
函数。
一般来说,只要我们改变一个系统来改变它的“输入”,就会发生这种逆转。如果我们正在改造一个系统来改变它的“输出”,那么就没有逆转 1 。
X -> A ---> A -> B ---> B -> Y
如果我有一个A -> B
函数并且我希望从中发出一些代替Y
的函数,我需要映射一个它的输出B -> Y
函数。这被称为协方差,因为我想要更改的内容(B
中的A -> B
)“因”我在其上映射的函数(B -> Y
“而异)。据称B
在A -> B
中处于积极地位。
如果我有一个A -> B
函数,并且我希望从中获取X
s的内容,我需要在其输入上映射X -> A
函数。这被称为逆变,因为我想要更改的内容(A
中的A -> B
)与“我在其上映射的函数(X -> A
”不同)。据说A
中的A -> B
处于否定位置。
1 高阶编程意味着我们可以转换一个系统来改变输出中输入的输入,这是输入到我们系统的输出......!术语“负位置” “和”积极的立场“有助于暗示否定的消极是积极的等等。
答案 1 :(得分:1)
由于您的mapping
正在对参数采取行动,因此订单被反转。您正在使用A -> B
函数使(C,A)
对符合(C,B) -> C
函数的类型。所以你最终获得的是(C,A) -> C
函数,它将对中的A
转换为B
作为初步步骤。
更一般地说,mapping
提供了逆变仿函数的示例,而不是协变仿函数(例如Haskell&#39; s Functor
类),其中订单不倒置。为了便于说明,这里是relevant Haskell package。