F#在lambda中调用对象方法的简写

时间:2010-09-29 11:30:50

标签: syntax f# language-features

我认为这与this question有些相关,但不确定,因为那里没有真正的答案,我在这里:
在Scala中你可以编写如下代码:

aStringArray.map(_.toUpperCase())

这是:

的简写
aStringArray.map(s => s.toUpperCase())

在F#中是否有类似的东西或实现它的方式(没有?运算符或大量使用反射)?如果这不可能,这是否被视为未来版本的语言功能? (我真的只是在闭包中调用对象上的方法的函数的冗长!)。

4 个答案:

答案 0 :(得分:6)

正如Dario指出的那样,Scala中的_.Foo()语法等功能目前在F#中不可用,因此您必须使用fun a -> a.Foo()显式编写lambda函数。

据我所知,这样的问题时不时出现在F#讨论中,所以F#团队肯定会考虑这个问题。这有点棘手(例如,您是否只允许成员使用或其他用途,例如_ + 10,以及lambda表达式的范围是什么?)此外,与其他功能相比,该功能的值相对较低可以做的事......无论如何,拥有它会很好!

这也可能是许多F#类型将操作公开为成员(在OO样式中可用)和模块中的函数(对于函数样式)的原因。我认为你可以认为它是一个很好的F#练习(但这取决于你的设计偏好)。 E.g:

type Foo(a:int) = 
  member x.Add(b:int) = a + b

// Attribute allows you to define module with the same name
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Foo = 
  let add b (v:Foo) = v.Add(b)

然后,您可以同时使用fun v -> v.Add(10)Foo.add 10来创建函数值。不幸的是,String类型没有与核心F#库中的所有函数相对应的模块,因此您必须自己编写它。

答案 1 :(得分:5)

只需使用fun s -> s.ToUpper()作为参数,即可创建Scala所使用的同类匿名函数。

请注意,来自Scala的这个漂亮的_技巧(当前)并不存在于F#中,但如果您没有调用对象方法,则可以使用部分评估,如

filter ((=) 42) list

答案 2 :(得分:1)

参见此论坛主题:

http://cs.hubfs.net/forums/permalink/13313/13319/ShowThread.aspx#13319

F#团队已多次在这片领域上空,但从未有过任何可行的事情。在这一点上,我认为我们将引入一种节省少于10个字符的新语法形式是值得怀疑的。

答案 3 :(得分:-1)

这不是你想要的答案,但是目前我通过创建虚拟静态函数来解决这个问题(如果我需要多次同样的事情),因为它比lambda语法更漂亮:

let toupper (s:string) = s.ToUpper()
aStringArray.map toupper