The following F# code works as I expected, printing `Matched as 'A':
let (|Char|_|) convf = function
| LazyList.Nil -> None
| LazyList.Cons (x, _) -> Some (convf x)
let test = function
| Char System.Char.ToUpper x -> printfn "Matched as %A" x
| _ -> printfn "Didn't match"
test (LazyList.of_list ['a'])
However, if I change Char
from a partial active pattern to a complete active pattern as follows:
let (|Char|NoChar|) convf = function
| LazyList.Nil -> NoChar
| LazyList.Cons (x, _) -> Char x
let test = function
| Char System.Char.ToUpper x -> printfn "Matched as %A" x
| NoChar System.Char.ToUpper -> printfn "Didn't match"
test (LazyList.of_list ['a'])
Then the code fails to compile, giving the following error message: error FS0191: Only active patterns returning exactly one result may accept arguments.
This example may look somewhat contrived, but it's a simplified version of an active pattern I tried to use in a Prolog lexer I've been working on in my spare time. I can easily rewrite my code to avoid this problem, but I'm curious about why this sort of code is disallowed.