Jane Street的Core lib具有以下功能:Fn.const
。
https://github.com/janestreet/core_kernel/blob/master/lib/fn.ml
let const c = (); fun _ -> c
val const:'a - > 'b - > “一个
生成一个只返回其第一个参数的函数
我真的不明白。
();
? let const c = fun () -> c
?这将给出一个以unit
为参数的函数,并始终返回初始c
。 let f = const 5
,f
将成为以'_a
为参数的函数。返回具有弱多态参数的函数的目的是什么? P.S。我看到Fn
模块中的几个函数在返回函数之前都有();
,();
的用法是什么?
答案 0 :(得分:10)
这个功能的目的是什么?在什么情况下我们必须使用它?
您需要在需要参数的函数的上下文中使用它,但您实际上并不关心参数,只想每次都返回相同的值。一个简单的例子是List.map (const 42) xs
,它将n个项目的列表转换为n个42个列表。
一个不那么愚蠢(但更抽象)的例子是一个能够产生某个值的函数,但在某些情况下(比如,如果某些事情没有成功)条件反而调用用户提供的函数来产生值而是给它一些有关情况的信息作为论点。在某些情况下,您可能不会对信息进行说明,并且每次只返回相同的默认值,因此const
可以在这里工作。
为什么要放();第一λ
在其内部表示以及生成的代码中,OCaml编译器实际上具有多参数函数。如果你定义一个像let f x y = ...
或let f x = fun y -> ...
这样的函数,OCaml实际上会在内部将它变成一个双参数函数(而不是一个返回另一个函数的单参数函数)。所以当你然后f 1 2
调用它时,这是对2参数函数的简单调用,这比替代函数更有效。但是,如果只执行f x
,则会生成一些额外的代码来创建闭包。这比直接返回闭包效率低。
因此,当您使用其所有参数调用函数时,此优化可以提高性能,但是当您不这样做时实际上会适得其反。在前面添加()
会禁用优化(因为该函数不再具有f x = fun y -> ...
形式)。由于const
仅用一个参数调用(直接调用const x y
没有意义,因为你可以写x
),这样可以提高性能。
为什么不把它写成让const c = fun() - > C?这将给出一个以单位为参数的函数,并始终返回初始c。
因为那时函数只能在需要unit
函数的上下文中工作,这将是绝大多数情况。例如,List.map (const 42) xs
现在只有在xs
是单位列表时才会起作用,而这几乎肯定不是。
答案 1 :(得分:3)
1。,2.和3.:见seppk的回答
4:OCaml类型系统使得函数不能返回多态值。您应该阅读Gabriel关于它的答案:What is the difference between 'a and '_l? overgeneralized curried fns