原型的可数#采用F#?

时间:2022-11-01 22:05:52

In JavaScript, using the Prototype library, the following functional construction is possible:

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

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

Note that this example code is equivalent to

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

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

I wondered if something similar is possible in F#:

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

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

without having to write:

无需写:

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

This would seem quite useful to me because then you don't have to write functions for every property to access them.

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

2 个解决方案

#1


2  

I saw your request on the F# mailing list. Hope I can help.

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

You could use type extension and reflection to allow this. We simple extend the generic list type with the pluck function. Then we can use pluck() on any list. An unknown property will return a list with the error string as its only contents.

您可以使用类型扩展和反射来实现此目的。我们使用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"

which produces the follow result in the interactive window:

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

> 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'"]

warm regards,

DannyAsher

> > > > >

>>>>>

NOTE: When using <pre> the angle brackets around

注意:使用

时使用尖括号

<'a>
didn't show though in the preview window it looked fine. The backtick didn't work for me. Had to resort you the colorized version which is all wrong. I don't think I'll post here again until FSharp syntax is fully supported.

#2


1  

Prototype's pluck takes advantage of that in Javascript object.method() is the same as object[method].

Prototype的pluck利用了Javascript object.method()中的那个与object [method]相同。

Unfortunately you can't call String.Length either because it's not a static method. You can however use:

不幸的是,你不能调用String.Length,因为它不是静态方法。但是你可以使用:

#r "FSharp.PowerPack.dll" 
open Microsoft.FSharp.Compatibility
words |> List.map String.length 

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

However, using Compatibility will probably make things more confusing to people looking at your code.

但是,使用兼容性可能会使查看代码的人更加困惑。

#1


2  

I saw your request on the F# mailing list. Hope I can help.

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

You could use type extension and reflection to allow this. We simple extend the generic list type with the pluck function. Then we can use pluck() on any list. An unknown property will return a list with the error string as its only contents.

您可以使用类型扩展和反射来实现此目的。我们使用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"

which produces the follow result in the interactive window:

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

> 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'"]

warm regards,

DannyAsher

> > > > >

>>>>>

NOTE: When using <pre> the angle brackets around

注意:使用

时使用尖括号

<'a>
didn't show though in the preview window it looked fine. The backtick didn't work for me. Had to resort you the colorized version which is all wrong. I don't think I'll post here again until FSharp syntax is fully supported.

#2


1  

Prototype's pluck takes advantage of that in Javascript object.method() is the same as object[method].

Prototype的pluck利用了Javascript object.method()中的那个与object [method]相同。

Unfortunately you can't call String.Length either because it's not a static method. You can however use:

不幸的是,你不能调用String.Length,因为它不是静态方法。但是你可以使用:

#r "FSharp.PowerPack.dll" 
open Microsoft.FSharp.Compatibility
words |> List.map String.length 

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

However, using Compatibility will probably make things more confusing to people looking at your code.

但是,使用兼容性可能会使查看代码的人更加困惑。