原型的可数#采用F#?

时间:2008-09-16 20:24:24

标签: javascript f# functional-programming prototypejs

在JavaScript中,使用Prototype库,可以实现以下功能构造:

var words = ["aqueous", "strength", "hated", "sesquicentennial", "area"];
words.pluck('length');
//-> [7, 8, 5, 16, 4]

请注意,此示例代码等同于

words.map( function(word) { return word.length; } );

我想知道F#中是否有类似的东西:

let words = ["aqueous"; "strength"; "hated";"sesquicentennial"; "area"]
//val words: string list
List.pluck 'Length' words
//int list = [7; 8; 5; 16; 4]

无需写:

List.map (fun (s:string) -> s.Length) words

这对我来说似乎非常有用,因为那样你就不必为每个属性编写函数来访问它们。

2 个答案:

答案 0 :(得分:2)

我在F#邮件列表上看到了您的请求。希望我能帮忙。

您可以使用类型扩展和反射来实现此目的。我们使用pluck函数简单地扩展通用列表类型。然后我们可以在任何列表上使用pluck()。未知属性将返回一个列表,其中包含错误字符串作为其唯一内容。

type Microsoft.FSharp.Collections.List<'a> with
    member list.pluck property = 
        try 
            let prop = typeof<'a>.GetProperty property 
            [for elm in list -> prop.GetValue(elm, [| |])]
        with e-> 
            [box <| "Error: Property '" + property + "'" + 
                            " not found on type '" + typeof<'a>.Name + "'"]

let a = ["aqueous"; "strength"; "hated"; "sesquicentennial"; "area"]

a.pluck "Length" 
a.pluck "Unknown"

在交互式窗口中生成以下结果:

> a.pluck "Length" ;; 
val it : obj list = [7; 8; 5; 16; 4]

> a.pluck "Unknown";;
val it : obj list = ["Error: Property 'Unknown' not found on type 'String'"]

热烈的问候,

DannyAsher

&GT; &GT; &GT; &GT; &GT;

注意:使用<pre&gt;时虽然在预览窗口中看起来不错,但

<'a>
周围的尖括号没有显示。反击不适合我。不得不求助于你的彩色版本,这是完全错误的。在完全支持FSharp语法之前,我不认为我会再次发布此处。

答案 1 :(得分:1)

原型pluck利用Javascript object.method()中的object[method]String.Length相同。

不幸的是,您无法调用#r "FSharp.PowerPack.dll" open Microsoft.FSharp.Compatibility words |> List.map String.length ,因为它不是静态方法。但是你可以使用:

Compatibility

http://research.microsoft.com/fsharp/manual/FSharp.PowerPack/Microsoft.FSharp.Compatibility.String.html

但是,使用{{1}}可能会让查看代码的人感到更加困惑。