要创建我的班级序列,
type MyInt(i:int) =
member this.i = i
[1;2;3] |> Seq.map(fun x->MyInt(x))
其中fun x->MyInt(x)
似乎是多余的。如果我能写Seq.map(MyInt)
但我不能。我能想到的一个解决方法是定义一个单独的函数
let myint x = MyInt(x)
[1;2;3] |> Seq.map(myint)
有更好的方法吗?
答案 0 :(得分: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>
。
答案 1 :(得分: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 }
或者,您的解决方法是一个很好的解决方案。
答案 2 :(得分:1)
要对此进行更新 - F# 4.0已将构造函数升级为第一类函数,因此现在可以在任何可以使用函数或方法的地方使用它们。
答案 3 :(得分: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)
。