我有一个函数getFullFitness
let getFullFitness population =
ResizeArray(population |> Seq.map snd) |> Seq.sum
我在函数realTick中模式匹配
let realTick population =
match(getFullfitness population) with
|(50) -> population
| _ -> childGeneration population
问题在线|(50) - >人口。由于getFullFitness返回一个整数和,如何在realTick中匹配0到50之间的值?
答案 0 :(得分:10)
一种方法是使用警卫 -
|t when t < 50 -> ...
答案 1 :(得分:9)
如果你在两个数字范围之间进行选择,就像你的例子一样,我愿意
只需使用if-then-else
表达式:
let realTick population =
let fitness = getFullFitness population
if 0 <= fitness && fitness <= 50 then
population
else
childGeneration population
或简单的警卫:
let realTick population =
match getFullFitness population with
| fitness when 0 <= fitness && fitness <= 50 ->
population
| _ ->
childGeneration population
如果您的实际选择更复杂,那么您可能想要使用 活跃的模式。与@pad不同,我会使用参数化的活动模式:
let (|BetweenInclusive|_|) lo hi x =
if lo <= x && x <= hi then Some () else None
let realTick population =
match getFullFitness population with
| BetweenInclusive 0 50 ->
population
| _ ->
childGeneration population
我发现偶尔有用的一个高阶活动模式是一般的 目的谓词:
let (|Is|_|) predicate x =
if predicate x then Some () else None
使用Is
你可以这样写:
let lessEq lo x = x <= lo
let greaterEq hi x = hi <= x
let realTick population =
match getFullFitness population with
| Is (greaterEq 0) & Is (lessEq 50) ->
population
| _ ->
childGeneration population
请注意,虽然这样的事情在这样的简单示例中是过度的, 在更复杂的场景中它可以很方便。我个人使用了积极的 与此类似的模式在优化中实现简化传递 编译器,该模式匹配大量原始情况 给这些原语的参数的操作和属性。
答案 2 :(得分:8)
在F#中,建议的范围模式匹配方法是使用active patterns。如果我们小心地操作模式名称,它将看起来非常接近我们想要的东西:
let (|``R0..50``|_|) i =
if i >= 0 && i <= 50 then Some() else None
let realTick population =
match(getFullfitness population) with
| ``R0..50`` -> population
| _ -> childGeneration population
OCaml支持范围上的模式匹配,但不太可能添加到F#。请参阅http://fslang.uservoice.com/forums/245727-f-language/suggestions/6027309-allow-pattern-matching-on-ranges上的相关用户语音请求。