2009-03-23 14 views
23

私はC#で関数を持っていますが、そのためにF#にそれを移植したいと思っています。残念ながら、私はF#でこれを表現する方法はないと思われる場合を打つ:私はこれはかなり簡単だろうと思ったのだF#で可変数の引数を取る関数を書くには

public static T Min<T>(params T[] p) where T : IComparable 
{ 
    T m1 = p[0]; 

    foreach (T v in p) 
    { 
     m1 = (m1.CompareTo(v) < 0) ? m1 : v; 
    } 

    return m1; 
} 

このC#関数を取るが、私は私どのように理解していませんF#で可変引数リストを指定します。私はこれを試してみました:

let rec Min l = 
    match l with 
    | [] -> 0 // should throw exception here 
    | [v] -> v 
    | (h::t) -> min h (Min t) 

が、C#のからそれを呼び出すことがMicrosoft.FSharp.Collections.Listを期待しています。 params T[]を期待することは可能ですか?もしそうなら、どのように?

+0

私はあなたの関数を次のように書き直すことをお勧めします:let min l = Seq.reduce min l – Juliet

+0

今、Seqメソッドを使っています。ちょうど私が探しているものです – Anteru

答えて

22

params配列は、単にJonノートのように属性を持つ配列です。パラメータの前に属性を追加します。

let test ([<ParamArray>] arr : 'a array) = 
    if arr.Length = 0 then invalid_arg "arr" 
    // .... 

あなたはタイプを指定する必要はありません。

let test ([<ParamArray>] arr) = ... // lets type inference do its thing 

しかし...パターンマッチングは、配列型では動作しません。助けになるようにアクティブなパターンを書くことができます。基本的には、F#コードやC#コードなど、より重要なことを決定する必要があります。高次関数の設計、タプルの使用、差別化された共用体の使用など、同じトレードオフが適用されます。C#はほとんどのものを表現することができません.F#は現在、C#が持ついくつかの小さな砂糖をサポートしていませんコンパイラなど)。

+2

しかし、F#では、パラメータ配列はメソッドでのみ定義することができます。モジュールで定義されているスタンドアロンの関数や関数では使用できません。 http://msdn.microsoft.com/en-us/library/vstudio/dd233213.aspxだから、テスト([] arr)は残念なことに動作しません –

+0

どういう意味ですか、うまくいきませんか?オープンシステム; let test([] arr)=();; - うまくコンパイルするようです。 – MichaelGG

+0

モジュールテスト= \ N tはテストをしましょう\ = \ N \ T \ Tせ試験 '([] ARR)=()\ N \ T \ T検定' \ nは 属性が聞かせて「で許可されていません'バインディング式 –

6

F#またはC#からこのメソッドを呼び出したいですか? This hubFS postは、F#が呼び出し側のパラメータ配列をサポートしていないことを示しているようですが、通常の型の注釈を使用して配列を作成し、ParamArrayAttributeでそれを飾ると、 C#の可変引数を使用します。

F#の属性でパラメータを装飾する方法を見てきたとは言いがちですが、必要に応じて迷惑をかけることがあります。This blog postにはいくつかの例がありますが、パラメータレベルではありません。

関連する問題