在我使用 OCaml 进行编程的实践中,我最近发现以下管道运算符对于创建函数非常有用。
let (>|) f g x = g (f x)
val ( >| ) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c = <fun>
我用它来替换如下代码:
fun s -> int_of_string s |> Int.hash
- : string -> int = <fun>
更简单的是:
int_of_string >| Int.hash
- : string -> int = <fun>
关联性很好:
int_of_string >| float_of_int >| string_of_float
- : string -> string = <fun>
这是否会对核心语言产生有价值的改进?如果是,如何提交这一贡献?
这称为函数组合。在 Haskell 中,运算符是
.
,而在 Elm 和 F# 中则是>>
。这些在纯函数式语言中运行良好,但不幸的是,在允许多态性和副作用的语言(例如 OCaml)中,它们会受到值限制,因此我认为不太可能被接受。此示例说明了该问题:
有关 OCaml 中值限制和多态性限制的详细信息,请参阅OCaml 手册。但其要点(据我理解)是,如果存在混合突变和多态性的可能性,则类型变量无法完全泛化,并将被弱类型变量取代,这些变量可能会在以后的某个时间点确定,例如首次使用时,但不能是多态的。对于组合函数的目的,不幸的是,这使得它非常具有限制性并且难以处理。
然而,OCaml 确实放宽了值限制,并且允许这样的函数,如果它们是语法函数的话。这意味着你可以这样做
但你最好还是这样做
或者
作为 glennsl 答案的补充,在部分应用多态函数时会遇到这种情况,但在将新名称绑定到多态函数时不会遇到这种情况。
g
但请注意,再次部分应用会产生另一个具有弱类型参数的函数。部分应用的这个问题的担心程度与该函数的寿命成正比。对于短暂存活的函数,如果使用偏应用不会损害代码的表达能力,您不应该犹豫使用它。