6

要创建我的班级序列,

type MyInt(i:int) =
    member this.i = i

[1;2;3] |> Seq.map(fun x->MyInt(x))

wherefun x->MyInt(x)似乎是多余的。如果能写就更好了Seq.map(MyInt)

但是我不能。我能想到的一种解决方法是定义一个单独的函数

let myint x = MyInt(x)
[1;2;3] |> Seq.map(myint)

有一个更好的方法吗?

4

4 回答 4

9

如果无端黑客不打扰你,你可以这样做:

///functionize constructor taking one arg
let inline New< ^T, ^U when ^T : (static member ``.ctor`` : ^U -> ^T)> arg =
  (^T : (static member ``.ctor`` : ^U -> ^T) arg)

type MyInt(i: int) =
  member x.i = i

[0..9] |> List.map New<MyInt, _>

编辑:正如 kvb 所指出的,可以使用更简单(并且更少hacky)的签名:

let inline New x = (^t : (new : ^u -> ^t) x)

请注意,这会切换类型 args,因此它变为New<_, MyInt>.

于 2012-04-10T19:10:42.560 回答
7

简而言之,没有。

对象构造函数不是 F# 中的一流函数。这是不使用类的另一个原因,这里最好使用有区别的联合:

type myInt = MyInt of int
let xs = [1;2;3] |> Seq.map MyInt

如果您不喜欢显式 lambda,则序列表达式在您的示例中看起来更好:

let xs = seq { for x in [1;2;3] -> MyInt x }

或者,您的解决方法是一个不错的解决方案。

于 2012-04-10T18:34:02.973 回答
1

为了对此进行更新 - F# 4.0已将构造函数升级为一等函数,因此它们现在可以在任何可以使用函数或方法的地方使用。

于 2015-12-27T01:43:00.853 回答
0

为此,我使用静态方法。原因是有时您的对象构造函数需要来自不同来源的两个参数,而我的方法允许您使用List.map2

type NumRange(value, range) =
    static member Make aValue aRange = new NumRange(aValue, aRange)

let result1 = List.map2 NumRange.Make values ranges

也不禁止部分应用:

let result2 =
    values
    |> List.map NumRange.Make
    |> List.map2 id <| ranges

如果你不喜欢id在这里使用,你可以使用(fun x y -> x y)哪个更易读。

于 2012-04-10T20:04:17.707 回答