consider following nonsense lambda:
function | [] -> "empty list" | hd::tl -> "not empty list"
this works fine. rewrite follows:
function | [] -> "empty list" | hd::tl & l -> "not empty list"
again, nonsense reasons (and know can achieve same effect using as
instead of &
, has code-golf problem that's not pertinent question). f# compiler tells me:
warning fs0025: incomplete pattern matches on expression. example, value '[]' may indicate case not covered pattern(s).
this doesn't make sense - explicitly handling case of []
in first rule. don't see changed first function second respect []
; neither function's second rule have matched yet second function gives warning. did add additional pattern matches anything.
of course, invoking second function empty list succeed.
is there valid reason why warning occurred, or f# pattern validation have quirks? see having cases when more advanced patterns employed, seems pretty basic one. if problem can't solved generally, seems type of case common enough merit special handling in compiler.
i think f# compiler being practical in case.
in end, second rule can expressed constraint on input list xs
:
xs = hd :: tl && xs = l
f# compiler doesn't seem explore &&
constraints. reasonable because constraints can arbitrarily complex , use of &
quite rare.
we have similar problem partial active patterns:
let (|empty|_|) = function | [] -> some() | _ -> none let (|nonempty|_|) = function | _ :: _ -> some() | _ -> none // warning fs0025 let f = function | empty -> "empty list" | nonempty -> "not empty list"
to fix issue, can:
- use
as
instead of&
, more appropriate sincel
binding. add wildcard pattern end eliminate warning. write
let f = function | hd::tl & l -> "not empty list" | _ -> "empty list"
suppress warning using
nowarn "25"
.