kasperhj
kasperhj

Reputation: 10482

Order of type constraints in F#

This works in F#4.0:

type Something<'a, 'b when 'b :> seq<'b>>() = 

This doesn't:

type Something<'b when 'b :> seq<'b>, 'a>() = 

Unexpected symbol ',' in type name. Expected '>' or other token.

What's the reason that the order of the type constraint matter?

Upvotes: 3

Views: 145

Answers (3)

Ray
Ray

Reputation: 3109

Along with the above answers, the ordering allows the constraints to depend on multiple types. e.g.

type Something<'a, 'b when 'b :> seq<'a>>() =

Note:seq<'a> not seq<'b>

Upvotes: 1

Luaan
Luaan

Reputation: 63732

Type constraints and type arguments are two different things. In your example, 'a and 'b are two type arguments, and when 'b :> seq<'b> is the (only) constraint.

Now, the way you've written your first example it seems to suggest that the type argument definitions have something to do with the type constraints, but that's only in the appearance. Note this (working) code:

type Something<'b, 'a when 'b :> seq<'b>>() = 
  member this.A (a : 'a, b : 'b) =
    ()

First, you define all the type arguments. Only afterwards come the type constraints, and the constraint still applies to 'b, not 'a - while it looks a bit confusing, the constraint expression isn't 'a when 'b :> seq<'b>, it's just the when 'b :> seq<'b>.

This is actually pretty much the same as in C#, another .NET language:

public class Something<TA, TB> where TA: someConstraint where TB: someOtherConstraint

The constraints are more visually separate in C#, so people don't tend to make the mistake you made in F#.

Upvotes: 4

John Palmer
John Palmer

Reputation: 25516

Because it is in the spec - the relevant part is this (from the start of section 5):

typar-defns:= < typar-defn, ..., typar-defn typar-constraints_opt>

the constraints need to go at the end.

In this typar-constraints must always start with when and can't appear anywhere else.

Upvotes: 9

Related Questions