Reputation: 6442
How can I make compiler ignore some downcast pattern matching warnings (FS0025) but must capture other FS0025 warnings in the same file?
For example, the first pattern match (Student studentName) = john
would never throw an error so I want the compiler to remove an unnecessary warning.
type Job = Student of string | Teacher of string
let john = Student "John"
(* FS0025: Incomplete pattern matches on this expression. For example,
the value 'Teacher _' may indicate a case not covered by the pattern(s). *)
let (Student studentName) = john
let (Teacher teacherName) = john // runtime error
I tried:
#nowarn "25"
let (Student studentName) = john
#warn "25"
let (Teacher teacherName) = john
But it doesn't show any warning error for let (Teacher teacherName) = john
.
Upvotes: 2
Views: 86
Reputation: 2058
Without access to GADTs, you have to add a bit of extra boilerplate in the form of an additional wrapper type:
type Student = Student of string
type Teacher = Teacher of string
type Job = StudentJob of Student | TeacherJob of Teacher
let john = Student "John"
let (Student studentName) = john // no warning
let (Teacher teacherName) = john // compile error
Upvotes: 1
Reputation: 10624
In this particular example, both cases have the same data, a single name string, so you could pattern match to get the name:
let name = match john with Student n | Teacher n -> n
You could add this as a member on the type if you're going to do it many times:
type Job =
| Student of string
| Teacher of string
member this.Name = match this with Student n | Teacher n -> n
let john = Student "John"
let name = john.Name
Upvotes: 1
Reputation: 12103
If you're willing to use a GADT to record in the type the constructor that was used you can write something like this (OCaml syntax, I don't have F# installed):
type student
type teacher
type _ job =
| Student : string -> student job
| Teacher : string -> teacher job
let john = Student "John"
Your first pattern-matching is then accepted without emitting a warning (it is total: there is only one constructor for a value of type student job
):
let (Student studentName) = john
Whilst the second one is rejected at type-checking time because student
and teacher
are not equal:
let (Teacher teacherName) = john
You can write functions ranging over all job
s by writing functions from 'a job
.
Upvotes: 2