2012-06-13 12 views
8

F#でこのhaskellをどうやって行うのですか?F#バージョンのhaskellパターンが一致する

add 1 2 x = 3 + x 
add 1 x y = 1 + x + y 
add z x y = z + x + y 
+0

私はhaskellを知らないのですが、ここでの目標は何ですか?これは、コンパイラがキャッチして解決する最適化のように見えます。私はパターンマッチングでF#に相当するものを書くのが遅いと思う。あなたは何を達成しようとしていますか? – gjvdkamp

+2

gjvdkampは、最適化ではなく、各ケースを読みやすくするための構文的なデバイスです。 'f 1 = x; f 2 = y 'は、f a = 1のa - > xとなる。 2 - > y' - http://www.haskell.org/onlinereport/decls.html#sect4.4.3.1 –

答えて

21

あなたは関数自体をオーバーロードすることはできませんが、直接、パターンマッチングを使用することができます:予想通り

let add z x y =    // curried multiple parameters 
    match z, x, y with  // convert to three-tuple to match on 
    | 1, 2, x -> 3 + x 
    | 1, x, y -> 1 + x + y 
    | z, x, y -> z + x + y 

使い方は次のとおりです。add 1 2 3

あなたが使用して喜んでいる場合タプルを引数として使うことができます(つまり、カレー化と部分的な適用を避ける)場合は、さらに短く書くこともできます。

let add =      // expect three-tuple as first (and only) parameter 
    function     // use that one value directly to match on 
    | 1, 2, x -> 3 + x 
    | 1, x, y -> 1 + x + y 
    | z, x, y -> z + x + y 

使い方は今です:Haskellではadd (1, 2, 3)

+0

ありがとう!私はf#パターンマッチングの例を探していましたが、サンプルに複数のパラメータが一致するものはありませんでした。私はあなたがこれを行えないという印象を与えられました。 –

+0

@ジミー:技術的には1つのタプルがここにマッチしているので間違っていませんでした... – ildjarn

+0

@ildjarn:2番目の例では、私が使用するものではないものの、currying /部分的なアプリケーションを失うので、これらの言語の最も有益な部分の1つです。 –

8

リコールそのパターンとの宣言のリストとしてgeneral form of functions:そう

f x1 .. xn = case (x1, .. xn) of 
       (pat1, ..., patn) -> e1 
       (pat2, ..., patn) -> e2 
       (pat3, ..., patn) -> e3 

f pat1 ... = e1 
f pat2 ... = e2 
f pat3 ... = e3 

case分析のためだけの糖でありますパターンマッチングで宣言レベルのパターンを使用せずに他の言語に同じ翻訳を行うことができます。

+0

私はそれが単なる事実であることを認識していますが、砂糖がhaskellに存在する理由は清潔であるため、f#で同様のものが存在することを期待していました。また、yamenが指摘したように、f# –

5

これは純粋に構文です。 Haskellのような言語は、標準MLとMathematicaは、彼らがさまざまな機能であるかのようにあなたが別の試合の例を書くことができ:

factorial 0 = 1 
factorial 1 = 1 
factorial n = n * factorial(n-1) 

のOCamlとF#のような言語は、単一の関数定義を持っており、中にmatchまたは同等のものを使用する必要のに対し、その本体:

let factorial = function 
    | 0 | 1 -> 1 
    | n -> n * factorial(n-1) 
01:あなたはこの構文を使用して何度も繰り返し、関数名をコピーする必要はありませんし、あなたがより簡単にマッチケースを考慮することができます

let factorial = function 
    | 0 -> 1 
    | 1 -> 1 
    | n -> n * factorial(n-1) 

注意

ヤーマンが書いたように、F#でlet f a b = match a, b with ...でカリングしてください。

古典赤黒木の実装では、私は標準MLとHaskellの関数名と右辺の複製は非常に醜い見つける:同等のOCamlまたはF#に比べ

balance :: RB a -> a -> RB a -> RB a 
balance (T R a x b) y (T R c z d) = T R (T B a x b) y (T B c z d) 
balance (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d) 
balance (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d) 
balance a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d) 
balance a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d) 
balance a x b = T B a x b 

let balance = function 
    | B, z, (T(R, y, T(R, x, a, b), c) | T(R, x, a, T(R, y, b, c))), d 
    | B, x, a, (T(R, z, T(R, y, b, c), d) | T(R, y, b, T(R, z, c, d))) -> 
     T(R, y, T(B, x, a, b), T(B, z, c, d)) 
    | a, b, c, d -> T(a, b, c, d)