嗨,我试图理解以下代码。该代码的目的是计算素数出现的次数。 factors
函数只是查找给定数字的素因数。
let smallArray = Array.Parallel.init 5 factors;;
let checkMap key map =
match Map.tryFind key map with
| Some i -> i
| None -> 0
let incr map (key:int) = Map.add key ((checkMap key map) + 1) map
Array.fold (List.fold incr) Map.empty smallArray;;
我卡住的地方是代码的最后一行。我不知道它是否先执行Array.fold或List.fold,但我猜应该是List.fold。下一步是将函数incr
应用于小数组,并将其放入一个空的映射中,但是函数incr
接受2个参数,据我所知,我们仅为其提供一个映射?有人可以解释一下吗?
答案 0 :(得分:1)
首先让我们总结一下此处涉及的功能类型:
List.fold : ('State -> 'T -> 'State) -> 'State -> 'T list -> 'State
Array.fold : ('State -> 'T -> 'State) -> 'State -> 'T [] -> 'State
incr : Map<int, int> -> int -> Map<int, int>
从类型上我们可以看到,List.fold
接受与incr
形状相同的函数,并接受两个参数并返回与第一个参数相同类型的值。在替换推断的类型之前,将incr
应用于List.fold
将产生具有以下类型的部分应用的函数:
(List.fold incr) : 'State -> 'T list -> 'State
,在将'State
和'T
替换为可以从incr
的应用程序推断出的类型之后,我们得到:
(List.fold incr) : Map<int, int> -> int list -> Map<int, int>
这又与incr
具有相同的形状,唯一的区别是int
的第二个incr
自变量在此处是int list
。并且由于Array.fold
与List.fold
具有相同的基本形状,因此我们可以像上述(List.fold incr)
一样使用incr
作为Array.fold
的第一个参数。
Array.fold (List.fold incr)
(如果部分应用)将产生以下类型:
(Array.fold (List.fold incr)) : Map<int, int> -> int list [] -> Map<int, int>
然后将 Map.empty
和smallArray
分别应用于最后一个参数作为初始值和要折叠的集合,以便:
Array.fold
与smallArray
叠在(List.fold incr)
上List.fold incr
依次折叠int list
中的每个smallArray
incr
将其结果累积到Map<int, int>
中,该结果源自传递给Map.empty
的初始Array.fold
值。