Is there a way to constrain one type parameter to be derived from another?
type Foo<'T, 'U when 'U :> 'T> =
member x.Bar() : 'T = upcast Unchecked.defaultof<'U>
This code produces the following errors:
Error 1 Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution
Error 2 This type parameter has been used in a way that constrains it to always be ''T'
Error 3 The static coercion from type 'T to 'T0 involves an indeterminate type based on information prior to this program point. Static coercions are not allowed on some types. Further type annotations are needed.
Warning 4 This construct causes code to be less generic than indicated by the type annotations. The type variable 'U has been constrained to be type ''T'.
Object, you'll apply constraints to the type parameter. For example, the base class constraint tells the compiler that only objects of this type or derived from this type will be used as type arguments.
A type constraint on a generic type parameter indicates a requirement that a type must fulfill in order to be accepted as a type argument for that type parameter. (For example, it might have to be a given class type or a subtype of that class type, or it might have to implement a given interface.)
Interface Type Constraint You can constrain the generic type by interface, thereby allowing only classes that implement that interface or classes that inherit from classes that implement the interface as the type parameter.
Value type constraint If we declare the generic class using the following code then we will get a compile-time error if we try to substitute a reference type for the type parameter.
No :(. This is one of the most unfortunate limitations of F# at the moment (in my opinion). See the Solving Subtype Constraints section of the spec, which states that
New constraints of the form type :> 'b are solved again as type = 'b.
This is really a shame since otherwise we could work around F#'s lack of generic variance:
let cvt<'a,'b when 'a :> 'b> (s:seq<'a>) : seq<'b> = // doesn't compile
s |> box |> unbox
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With