I got a question, mostly because I found a case where classes and subtyping was needed.
let say we got some function
let IsA<'item, 'input> (subject: 'input) =
match subject with
| :? 'item as item -> Some item
| _ -> None
is there a way to constraint the generic types to allow this.
The alternative is to do a IsA function for all subtype constrains.
This is a dummy case, but it clearly describes what I need to do.
I'm not exactly sure what your motivation here is. You can certainly box
the subject
before pattern matching on the value:
let IsA<'item, 'input> (subject: 'input) =
match box subject with
| :? 'item as item -> Some item
| _ -> None
This lets you call IsA
on various things, including the ones that make sense (but also, because of the boxing, some that cannot possibly make sense). You need to constrain the 'item
type parameter, either by explicitly saying IsA<Cat, _>
or by having an annotation elsewhere:
type Animal() = class end
type Dog() = inherit Animal()
type Cat() = inherit Animal()
let dogAnimal = Dog() :> Animal
let asCat : Cat option = IsA dogAnimal
let asDog : Dog option = IsA dogAnimal
let asCat2 : Cat option = IsA (System.Random())
In principlie, it would be nice if the last case with Random
was not allowed. Unfortunately, you cannot specify a constraint for this though. The following does not work:
let IsA<'item, 'input when 'item :> 'input> (subject: 'input) =
match subject with
| :? 'item as item -> Some item
| _ -> None
The issue is discussed, for example, here: How to constrain one type parameter by another