3

Pythonでは、次のように記述できます。

def add(a, b, c):
    return a + b + c

list_of_args = [4, 5, 6]
print(add(*list_of_args))

前のアスタリスクはlist_of_args、反復可能要素を展開して、その要素がパラメーターa、b、およびcの値になるようにします。

F#でも同様のことができますか?具体的には、私は優れた、または慣用的なF#ソリューションを探しており、リフレクションなどをいじくり回したくありません。

4

3 に答える 3

5

あなたはこれを行うことができます:

type T =
  static member func([<ParamArray>] args: 'T[]) = printfn "%A" args

T.func(1, 2, 3)

let args = [|1; 2; 3|]
T.func(args)

どちらの呼び出しもprint[|1; 2; 3|]です。

于 2013-01-25T15:35:24.493 に答える
2

F#には、このようなものはそのままではありません。主な理由は、F#は静的に型指定された言語であり、同様のパターンをサポートするのが難しいためです(リストには、1つの型の値のみが含まれる場合がありますが、関数には異なるパラメーターが含まれる場合があります)。

リンクされた回答で述べたように、リフレクションを使用して同様のアイデアをエミュレートできます。これは遅くて安全ではありませんが、これを行う正当な理由がある場合は、試してみてください。

前の回答の関数といくつかのアクティブなパターンを使用してtupleToList、次のように書くことができます。

// Converts any F# tuple to a list of objects using reflection
let tupleToList t = 
    if Microsoft.FSharp.Reflection.FSharpType.IsTuple(t.GetType()) 
        then Some (Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields t |> Array.toList)
        else None

// Active pattern that accepts any object and extracts its members
// if it is a tuple or a sequence of values (e.g. list)
let (|Arguments|_|) (a:obj) = 
  match a, tupleToList a with
  | _, Some t -> Some t
  | :? System.Collections.IEnumerable as l, _ -> 
      l |> Seq.cast |> List.ofSeq |> Some
  | _ -> None

// Treat the argument as an int (this may fail)
let (|Int|_|) (a:obj) = match a with :? int as n -> Some n | _ -> None

// Function that assumes to get three integers
let f (Arguments [Int a;Int b;Int c]) = 
  printfn "%d" (a + b + c)

f (1, 2, 3) // Call with tuple
f [1;2;3]   // Call with a list
f (1, "hi", 3, 141.1)  // This will fail at runtime, but compiler allows it :-(

これはおそらくあまり慣用的なF#ではなく、回避しようとしますが、うまくいく可能性があります。

于 2013-01-25T10:48:40.467 に答える
1

ここであなたの意図を知ることは興味深いでしょう。特定の関数の引数をファーストクラスの値として扱う方法が必要な場合は、値のタプルを単一の引数として受け取るように関数を定義するだけです。

let f (a, b, c) = a + b + c
let args = (1, 2, 3)
let result = f args

メソッドの場合、これは実際には「デフォルトスタイル」です。唯一の欠点:そのような関数/メソッドで部分適用を実際に使用することはできません。

于 2013-01-25T13:51:56.200 に答える