Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to constrain one type parameter by another

Tags:

f#

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'.

like image 933
Daniel Avatar asked Oct 04 '10 17:10

Daniel


People also ask

Which of the following keyword is used to apply constraints on type parameter?

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.

What is type constraint?

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.)

What is the purpose of an interface constraints on a type parameter?

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.

Which of the following generic constraints restricts the generic type parameter to an object of the class?

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.


1 Answers

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
like image 159
kvb Avatar answered Oct 22 '22 06:10

kvb