6

クラスのシーケンスを作成するには、

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

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

fun x->MyInt(x)冗長なようです。書けたらいいのにSeq.map(MyInt)

でもできないんです。私が考えることができる1つの回避策は、別の関数を定義することです

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が指摘したように、より単純な(そしてハッキーではない)署名を使用できます:

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

これにより、型引数が切り替わるため、になりNew<_, MyInt>ます。

于 2012-04-10T19:10:42.560 に答える
7

要するに、違います。

オブジェクトコンストラクターは、F#のファーストクラスの関数ではありません。これは、クラスを使用しないもう1つの理由です。ここでは、識別された共用体を使用することをお勧めします。

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

明示的なラムダが気に入らない場合は、例のシーケンス式の方が見栄えがします。

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

私はこの目的のために静的メソッドを使用します。その理由は、オブジェクトコンストラクターが異なるソースから取得した2つの引数を必要とする場合があり、私のアプローチでは次を使用できるため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 に答える