在JavaScript中,使用原型库,可以进行以下功能构造:

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


这对我来说似乎很有用,因为您不必为每个属性都编写函数来访问它们。

最佳答案

我在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“长度” ;;
val it:obj list = [7; 8; 5; 16; 4]

> a.pluck“未知”;
val it:obj list = [“错误:在类型'String'上找不到属性'Unknown'”]


温暖的问候,

丹尼·阿舍

>
>
>
>
>

注意:使用>时,虽然在预览窗口中没有显示周围的尖括号,但看起来不错。反勾号对我不起作用。不得不向您诉诸所有错误的彩色版本。在完全支持FSharp语法之前,我认为我不会在这里再次发表文章。

09-25 19:44