- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我问了this question不久前。这是关于以下箭头法则:
arr fst . first f = f . arr fst -- (.) :: Category k => k b c -> k a b -> k a c
在帖子下评论Asad Saeeduddin用自然变换来解释它。我想检查一下他们的解释是否正确,并将其与 Bartosz Milewski's article on natural transformations 进行比较.
因此,自然变换的定义是:
我们有两个类别 C
和 D
以及仿函数 F, G : C ~> D
。自然变换 α
是 D
中的一组箭头,使得:
F
的结果指向 G
的结果。也就是说,C
中的每个对象 a
都存在一个箭头(称为 α
的组件 a
) α_a::F a ~> G a
.f::a ~> b
,a
和 b
都是 C
中的对象,成立: Gf。 α_a = α_b 。 Ff
。这就是自然。基本上,我们需要弄清楚我们的例子中有哪四个变量:C
、D
、F
和G
.
据我所知:
C
和D
是同一类任意类型,k a b
是其中的箭头,其中k
是我们正在使用的 Arrow
实例。因此,F
和G
是内仿函数。
F
是 (, c)
而 G
是 Identity
。换句话说,如果我们不再使用类型,我们将 F
映射到 first
并将 G
映射到 id
。从类型的角度考虑NOT可能会更容易,因为 Category
和 Arrow
类帮助我们构造类别的箭头,而不是对象
这样对吗?
此外,Bartosz Milewski wrote those ideas down像那样:
fmap f . alpha = alpha . fmap f
据我所知,我们需要一个更通用的形式来实现我们的目的,如此处 alpha::forall a。 F a -> G a
仅将 Hask 作为其工作的类别进行处理。还是我错了? fmap
在这幅图中的哪个位置?
最佳答案
As far as I get it:
C
andD
are the same category of arbitrary types,k a b
being arrows in it, wherek
is theArrow
instance we are working with.Therefore,F
andG
are endofunctors.
F
is(, c)
andG
isIdentity
. In other words, if we no longer work with types, we mapF
withfirst
andG
withid
.[...]
是的,就是这样。 arr fst::k (b, c) b
中 k
和 c
的每个选择都为我们提供了 ( , c)
endofunctor 和 k
类中的恒等仿函数。执行特化给我们一个看起来更像自然转换的签名:
arr @K (fst @_ @C) :: forall b. K (b, C) b
Moreover, Bartosz Milewski wrote those ideasdownlike that:
fmap f . alpha = alpha . fmap f
As far as I get it, we need a more general form for our purposes ashere
alpha :: forall a. F a -> G a
deals with Hask only as thecategory it works with. Or am I wrong? Which place doesfmap
have inthis picture?
也正确。 fmap
必须被所涉及的仿函数的任何适当的态射映射所取代。在您的示例中,这些恰好是 first
和 id
,正如您之前注意到的那样,这让我们回到了我们开始的箭头法则。
(至于用更一般的类比替换fmap
,Functor
的方法,它从特定的仿函数态射映射中抽象出来,需要进行适当的安排,以便我们可以在 Haskell 代码中表达涉及非 Hask 类别的仿函数。您可能想看看 constrained-categories 和 data-category 是如何处理的。)
关于haskell - `arr fst` 是如何自然转换的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63639328/
这个问题在这里已经有了答案: Unexpected result with `in` operator chaining (1 个回答) Chaining "is" operators (4 个回答)
我想知道为什么下面的代码会崩溃。 int main( ) { int arr = 1 && arr; return 0; } 但不是下面的代码 int main( ) {
什么是计算一组数字平均值的更准确方法,ARR[0]/N+ARR[1]/N...+ARR[N-1]/N 或 (ARR[0]+ARR[1]...+ARR[N-1])/N? (ARR 是一组数字,N 是该组
#include using namespace std; int main() { int arr[5] = {5, 8, 1, 3, 6}; int len = *(&arr +
在下面的代码中,是什么意思 vector avector (arr, arr + sizeof(arr) / sizeof(arr[0]) ); 在 main() 中? vector bubbleSo
我主要是这样使用的: arr.push(element) 但我见过有人这样使用: arr.push.apply(arr, element) 这两种方法有什么区别? 最佳答案 我认为在使用“列表”时更常
任务是重新排列一个数组,使 arr[i] 变成 arr[arr[i]],复杂度为 O(1)额外的空间。 例子: 2 1 3 5 4 0 变成: 3 1 5 0 4 2 我可以想到一个O(n²) 的解决
今天我来了一篇 Eric Lippert 的文章他试图澄清运算符优先级和评估顺序之间的迷思。最后有两个代码片段让我感到困惑,这是第一个片段: int[] arr = {0};
view和copy的意思是不同的,如果你有一个view,那么如果你改变1另一个也应该改变,如果你有一个副本那么改变1应该不会影响另一个 有 3 种制作 view 的方法/copy数组的 arr_2 =
这个问题在这里已经有了答案: How does *(&arr + 1) - arr give the length in elements of array arr? (3 个回答) Why are
我想将自己的值输入到 20 个大数组中,并将其复制到 2 个 10 个小数组中,然后必须打印第二个数组的值。我收到错误 ArrayIndexOutOfBoundsException 我的代码有什么问题
我是 C++ 新手。我正在尝试实现一个堆栈。我声明 arr默认构造函数中的命名变量。 但是当我编译我的代码时,我收到一条错误消息 'arr' was not declared in this scop
这个问题已经有答案了: Pointers - Difference between Array and Pointer (2 个回答) 已关闭 6 年前。 (C语言)之间有什么区别 int * a i
这个问题已经有答案了: How come an array's address is equal to its value in C? (6 个回答) 已关闭 4 年前。 这两个打印有什么区别,我在两
是一样的 char* s1[size]; 到 char** s2 = malloc(size * sizeof(char*)); 它们有什么区别吗? 最佳答案 理论上,*arr[]和**arr是不同的
我有一个字符串数组 arr[5][8] = {...} (声明了每个字符串),我试图了解 arr[3 的值是什么] - arr[2] 是什么以及它的类型是什么。我无法理解为什么地址之间的差异以字节为单
var arr = [foo,bar,xyz]; arr[arr.indexOf('bar')] = true; 在 JS 中有更简单的方法吗? 最佳答案 你可以只使用对象。 var obj = {f
这个问题在这里已经有了答案: What is the difference when we use array names instead of spread operator? (3 个答案) 关
在修改屏蔽数组中的数据时,我没想到会出现以下行为。似乎可以使用 [] 操作数修改某些值,但不是全部。但是,如果您访问它的数据属性,那么您可以修改所有内容。仅当元组中某个单元格的掩码中存在 True 值
我不明白如何确定以下元素: *(arr+1)[1] - 7 被打印出来。 **(arr+1) - 打印 4。 #include int main() { int arr[3][3]={1,2
我是一名优秀的程序员,十分优秀!