Multifactor activated templates returning FS0722 error Only active templates returning exactly one result can accept arguments

Since I just found the Japanese pages about this error, I thought, let me log and ask here as my Japanese variety is rusty.

If I have the following active FSharp template (simplified example):

let (|InRange|OutOfRange|) from too =
    function
    | input when input >= from && input <= too -> InRange
    | _ -> OutOfRange

      

It compiles fine and shows its type as:

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

      

But when I try to use it, that is, as follows, it throws an error:

let test i = match i with
             | InRange 10 20 -> "in range"
             | _ -> "out of range"

      

Throws: error FS0722: only active templates returning exactly one result can take arguments

I can resolve this by turning it into two one parameter active patterns, each returning None / Some (x), but I am still wondering why I am not allowed to do this and / or is there a syntax I can use that I am not I know. I am also wondering why it compiles, but I cannot use it?

+3


source to share


1 answer


The simplest solution would be to refactor this into a partial active template :

let (|InRangeInclusive|_|) lo hi x =
    if lo <= x && x <= hi then Some () else None

      

Then you can even combine them like this:

let test i = match i with
         | InRangeInclusive 10 20 -> "in first range"
         | InRangeInclusive 42 100 -> "in second range"
         | _ -> "out of range"

      



Note that I took it upon myself to give the template a better name, because those who will be using your code might be confused about its corner case behavior.

I'm still wondering why I am not allowed to do this?

Why can't non-partial active templates be parameterized in F #?

+6


source







All Articles