9

F# でこの Haskell をクリーンに実行するにはどうすればよいですか?

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

3 に答える 3

22

You can't overload the function itself, but you can use pattern matching directly:

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

Usage is as expected: add 1 2 3

If you're willing to use tuples as arguments (ie forgo currying and partial application), you can even write it more shorthand:

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

Usage now is: add (1, 2, 3)

于 2012-06-13T13:20:32.353 に答える
8

Haskell では、関数の一般的な形式が、パターンを含む宣言のリストであることを思い出してください。

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

分析のための単なる砂糖ですcase

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

したがって、宣言レベルのパターンを使用せずに、パターン マッチングを使用して他の言語に同じ翻訳を行うことができます。

于 2012-06-13T13:38:55.553 に答える
5

これは純粋に構文上の問題です。Haskell、Standard ML、Mathematica などの言語を使用すると、さまざまな一致ケースを別の関数であるかのように書き出すことができます。

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

一方、OCaml や F# などの言語では、単一の関数定義とmatchその本体での使用または同等のものが必要です。

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

この構文を使用して関数名を何度もコピーする必要はなく、一致ケースをより簡単に因数分解できることに注意してください。

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

yamen さんが書いたようにlet f a b = match a, b with ...、F# でカリー化を行います。

古典的な赤黒木の実装では、標準 ML と Haskell の関数名と右辺の重複が非常に見苦しいと思います。

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

同等の OCaml または F# との比較:

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)
于 2012-06-15T10:48:52.710 に答える