Dax*_*ohl 13 f# functional-programming currying named-parameters
我刚刚开始使用F#,看看如何使用currying将第一个参数预加载到函数中.但是如何用第二,第三或其他任何参数来做呢?命名参数会使这更容易吗?是否有任何其他功能语言具有命名参数或其他方式使currying对参数顺序无动于衷?
Bri*_*ian 19
通常你只使用lambda:
fun x y z -> f x y 42
Run Code Online (Sandbox Code Playgroud)
是一个像'f'的函数,但第三个参数绑定到42.
你也可以使用组合器(就像有人在评论中提到Haskell的"翻转"),它重新排序参数,但我有时会发现这令人困惑.
请注意,大多数curried函数都是编写的,因此最有可能部分应用的参数首先出现.
F#命名了方法的参数(不是let-bound函数值),但这些名称适用于'tupled'参数.命名的咖喱参数没有多大意义; 如果我有两个参数curried函数'f',我会期望给出
let g = f
let h x y = f x y
Run Code Online (Sandbox Code Playgroud)
然后'g'或'h'可替代'f',但'named'参数使得这不一定是真的.也就是说,"命名参数"可能与语言设计的其他方面交互不良,我个人并不知道"命名参数"的良好设计与"一流咖喱函数值"相互作用.
只是为了完整 - 并且因为你询问了其他功能语言 - 这就是你在OCaml中做到的,可以说是F#的"母亲":
$ ocaml
# let foo ~x ~y = x - y ;;
val foo : x:int -> y:int -> int = <fun>
# foo 5 3;;
- : int = 2
# let bar = foo ~y:3;;
val bar : x:int -> int = <fun>
# bar 5;;
- : int = 2
Run Code Online (Sandbox Code Playgroud)
因此,在OCaml中,您可以使用其名称(y在上面的示例中)对您想要的任何命名参数进行硬编码.
正如你所发现的那样,微软选择不实现这个功能......在我看来,这不是"与语言设计的其他方面的不良互动"......更可能是因为这需要额外的努力(在语言实现中)以及将语言带到世界的延迟 - 实际上只有少数人会(a)意识到OCaml的"降级",(b)无论如何都要使用命名函数参数.
我是少数,并使用它们 - 但它确实是在F#中使用本地函数绑定轻松模拟的:
let foo x y = x - y
let bar x = foo x 3
bar ...
Run Code Online (Sandbox Code Playgroud)
OCaml是F#所基于的语言,它具有可以按任何顺序指定的标记(和可选)参数,您可以根据这些参数的名称部分应用函数.我不相信F#有这个功能.
您可以尝试创建类似Haskell flip函数的东西.创建在参数列表中进一步跳转参数的变体应该不会太难.
let flip f a b = f b a
let flip2 f a b c = f b c a
let flip3 f a b c d = f b c d a
Run Code Online (Sandbox Code Playgroud)