多案例参数化活动模式返回错误FS0722只有返回一个结果的活动模式可以接受参数

Abe*_*bel 4 f# compiler-errors active-pattern

由于我只发现了关于这个错误的日文页面,我想,让我们记录它并在这里问,因为我的日语有点生疏.

如果我有以下FSharp活动模式(简化示例):

let (|InRange|OutOfRange|) from too =
    function
    | input when input >= from && input <= too -> InRange
    | _ -> OutOfRange
Run Code Online (Sandbox Code Playgroud)

它完美编译并显示其类型:

val ( |InRange|OutOfRange| ) :
  from:'a -> too:'a -> _arg1:'a -> Choice<unit,unit> when 'a : comparison
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用它时,即如下所示,它会抛出一个错误:

let test i = match i with
             | InRange 10 20 -> "in range"
             | _ -> "out of range"
Run Code Online (Sandbox Code Playgroud)

抛出:错误FS0722:只有返回一个结果的活动模式可以接受参数

我可以通过把它变成两个单例参数化的活动模式来解决它,每个都返回None/Some(x),但我仍然想知道为什么我不被允许这样做和/或是否有我可以使用的语法我是不知道.我也想知道它为什么编译,但我不能用它?

byt*_*ter 7

最简单的解决方案是将其重构为部分活动模式:

let (|InRangeInclusive|_|) lo hi x =
    if lo <= x && x <= hi then Some () else None
Run Code Online (Sandbox Code Playgroud)

然后你甚至可以将它们组合成这样的东西:

let test i = match i with
         | InRangeInclusive 10 20 -> "in first range"
         | InRangeInclusive 42 100 -> "in second range"
         | _ -> "out of range"
Run Code Online (Sandbox Code Playgroud)

注意,我冒昧地给这个模式一个更好的名字,因为那些使用你的代码的人可能会对它的角色案例的行为感到困惑.

我仍然想知道为什么我不允许这样做

为什么不能在F#中参数化非部分活动模式?