f# - 带有活跃模式的 FizzBu​​zz

标签 f# fizzbuzz active-pattern

我试图了解事件模式,所以我在玩 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)

这基本上是正确的方法,还是有更好的方法在这里使用事件模式?难道我不能做findMatch使用 int 而不是 int 选项?

最佳答案

Daniel 的第一个解决方案可以简化,因为您实际上不需要为 FizzBuzz 定义单独的事件模式。 .案例可谓兼具FizzBuzz匹配,可以用模式语言很好地表达:

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" 
  | _ -> "" 

关于f# - 带有活跃模式的 FizzBu​​zz,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10887506/

相关文章:

f# - 将 F# 管道运算符(<|、>>、<<)转换为 OCaml

f# - F#中的树表示

f# - 重用 F# 事件模式结果

javascript - 带 for 循环的 Fizzbuzz 游戏

compiler-errors - 返回错误 FS0722 的多情况参数化事件模式仅返回一个结果的事件模式可以接受参数

f# - 受歧视工会中的 curry 争论

f# - 解决枚举上的不完整模式匹配

.net - dotnet ef 迁移列表在迁移文件夹中找不到迁移

f# - 如何在 F# 中编写 Fizzbuzz

c - C 语言 Fizzbuzz 程序