4

私はアクティブパターンを理解しようとしているので、FizzBu​​zzで遊んでいます:

let (|Fizz|_|) i = if i % 3 = 0 then Some Fizz else None
let (|Buzz|_|) i = if i % 5 = 0 then Some Buzz else None
let (|FizzBuzz|_|) i = if i % 5 = 0 && i % 3 = 0 then Some FizzBuzz else None

let findMatch = function
    | Some Fizz -> "Fizz"
    | Some Buzz -> "Buzz"
    | Some FizzBuzz -> "FizzBuzz"
    | _ -> ""

let fizzBuzz = seq {for i in 0 .. 100 -> Some i}
                |> Seq.map (fun i -> i, findMatch i)

これは基本的に正しいアプローチですか、それともここでアクティブパターンを使用するためのより良い方法がありますか?findMatchintオプションの代わりにintを取得させることはできませんか?

4

3 に答える 3

10

Daniel の最初のソリューションは単純化できます。これは、FizzBuzz. ケースは、パターン言語でうまく表現できる、両方Fizzと一致として記述できます。Buzz

let findMatch = function 
  | Fizz & Buzz -> "FizzBuzz" 
  | Fizz -> "Fizz" 
  | Buzz -> "Buzz" 
  | _ -> "" 

let fizzBuzz = [ for i in 0 .. 100 -> findMatch i ]

とのFizz & Buzz両方が一致する場合、パターンは一致します。これは、パターンが最初に一致するという事実に依存しているため、この場合は順序が関係します。また、最後の行を私が好むスタイルに少し短くし、少し短くしました (ただし、意見はさまざまです)。FizzBuzz

または、単一目的のアクティブ パターンをあまり多く定義したくない場合は、入力が指定された数値で割り切れるかどうかをテストするパラメーター化されたアクティブ パターンを記述することもできます。

let (|DivisibleBy|_|) by n = if n%by=0 then Some DivisibleBy else None

let findMatch = function 
  | DivisibleBy 3 & DivisibleBy 5 -> "FizzBuzz" 
  | DivisibleBy 3 -> "Fizz" 
  | DivisibleBy 5 -> "Buzz" 
  | _ -> "" 
于 2012-06-05T04:27:01.950 に答える
8

あなたのfindMatch機能は次のとおりです。

let findMatch = function
    | FizzBuzz -> "FizzBuzz" (* should be first, as pad pointed out *)
    | Fizz -> "Fizz"
    | Buzz -> "Buzz"
    | _ -> ""

最後の数行を次のように書き換えることができます。

let fizzBuzz = Seq.init 100 (fun i -> i, findMatch i)

あなたのアクティブなパターンは問題ありません。1 つの代替方法は、完全なアクティブ パターンを使用することです。

let (|Fizz|Buzz|FizzBuzz|Num|) i = 
    match i % 3, i % 5 with
    | 0, 0 -> FizzBuzz
    | 0, _ -> Fizz
    | _, 0 -> Buzz
    | _ -> Num i
于 2012-06-04T20:08:41.427 に答える
3

関数がパラメーターとして受け取るSomeように(不要) を削除します。findMatchint

let findMatch = function
    | FizzBuzz -> "FizzBuzz" (* Should be the first pattern *)
    | Fizz -> "Fizz"
    | Buzz -> "Buzz"
    | _ -> ""

let fizzBuzz = seq { for i in 0..100 -> i, findMatch i }
于 2012-06-04T20:15:15.637 に答える