Fsharp: SRTP reports a required constraint (twice) that has already been specified

Created on 11 Oct 2018  路  7Comments  路  Source: dotnet/fsharp

Type resolution reports FS0001 and FS0043 with the same error, that a constraint is required - but that constraint is already specified

Repro steps

Crazy code sample:

type Tuple =
    static member inline TupleMap ((a, b),          _ : Tuple) = fun f -> (f a, f b)
    static member inline TupleMap ((a, b, c),       _ : Tuple) = fun f -> (f a, f b, f c)
    static member inline TupleMap ((a, b, c, d),    _ : Tuple) = fun f -> (f a, f b, f c, f d)

    static member inline Map f (x: 'Tin) : 'Tout =
        let inline call_2 (a: ^a, b : ^b) = ((^a or ^b) : (static member TupleMap : ^b * _ -> ^t) (b, a))
        call_2 (Unchecked.defaultof<Tuple>, x) f

type IOption<'T> =
    abstract member Value : 'T

module Something = 
    let inline tupleMap f x = Tuple.Map f x

    let inline addOptionValues< ^value, ^options, ^values, 'item when 
                                  'item :> IOption< ^value>
                                  and (Tuple or ^options) : (static member TupleMap : ^options * Tuple -> ('item -> ^value) -> ^values)>
                                  (addUp : ^values -> ^value, sourceOptions : ^options) =
        let getValue (i : 'item) = i.Value
        let allValues : ^values = tupleMap getValue sourceOptions
        let result : ^value = addUp allValues
        result

The line

        let allValues : ^values = tupleMap getValue sourceOptions

Gives the errors

Error   FS0043  A type parameter is missing a constraint 'when (Tuple or  ^options) : (static member TupleMap :  ^options * Tuple -> ('item ->  ^value) ->  ^values)'   
Error   FS0001  A type parameter is missing a constraint 'when (Tuple or  ^options) : (static member TupleMap :  ^options * Tuple -> ('item ->  ^value) ->  ^values)'   

Related information

Provide any related information

  • Windows 10
  • Visual F# Tools 10.2 for F# 4.5 15.8.0.0. Commit Hash: 55a3dc3231c95c77f81ee53f7d29152029da7408.
  • Microsoft Visual F# Tools 10.2 for F# 4.5
Area-Compiler bug

Most helpful comment

Hi @marklam,

I believe this is the same issue as #4924 (which you may want to read for background information). This should make your code work:

type Tuple =
    static member inline TupleMap ((a, b),          _ : Tuple) = fun f -> (f a, f b)
    static member inline TupleMap ((a, b, c),       _ : Tuple) = fun f -> (f a, f b, f c)
    static member inline TupleMap ((a, b, c, d),    _ : Tuple) = fun f -> (f a, f b, f c, f d)

    static member inline Map f (x: 'Tin) : 'Tout =
        let inline call_2 (a: ^a, b : ^b) = ((^a or ^b) : (static member TupleMap : ^b * _ -> ^t) (b, a))
        call_2 (Unchecked.defaultof<Tuple>, x) f

type IOption<'T> =
    abstract member Value : 'T

module Something =
    let inline tupleMap f x = Tuple.Map f x

    let inline addOptionValues (addUp : ^values -> ^value, sourceOptions : ^options) =
        let getValue (i : #IOption<_>) = i.Value
        // or instead possibly
        (* let getValue (i : #IOption< ^value>) = i.Value *)
        let allValues : ^values = tupleMap getValue sourceOptions
        let result : ^value = addUp allValues
        result

All 7 comments

Hi @marklam,

I believe this is the same issue as #4924 (which you may want to read for background information). This should make your code work:

type Tuple =
    static member inline TupleMap ((a, b),          _ : Tuple) = fun f -> (f a, f b)
    static member inline TupleMap ((a, b, c),       _ : Tuple) = fun f -> (f a, f b, f c)
    static member inline TupleMap ((a, b, c, d),    _ : Tuple) = fun f -> (f a, f b, f c, f d)

    static member inline Map f (x: 'Tin) : 'Tout =
        let inline call_2 (a: ^a, b : ^b) = ((^a or ^b) : (static member TupleMap : ^b * _ -> ^t) (b, a))
        call_2 (Unchecked.defaultof<Tuple>, x) f

type IOption<'T> =
    abstract member Value : 'T

module Something =
    let inline tupleMap f x = Tuple.Map f x

    let inline addOptionValues (addUp : ^values -> ^value, sourceOptions : ^options) =
        let getValue (i : #IOption<_>) = i.Value
        // or instead possibly
        (* let getValue (i : #IOption< ^value>) = i.Value *)
        let allValues : ^values = tupleMap getValue sourceOptions
        let result : ^value = addUp allValues
        result

Thanks!

@dsyme This is a smaller repro than #4924, but does surface as a different issue. I won't close this as a dupe because of that, but I'll leave that call to you

@marklam the correct solution for your code is:

type Tuple =
    static member inline TupleMap ((a, b),          _ : Tuple) = fun f -> (f a, f b)
    static member inline TupleMap ((a, b, c),       _ : Tuple) = fun f -> (f a, f b, f c)
    static member inline TupleMap ((a, b, c, d),    _ : Tuple) = fun f -> (f a, f b, f c, f d)

    static member inline Map f (x: 'Tin) : 'Tout =
        let inline call_2 (a: ^a, b : ^b) = ((^a or ^b) : (static member TupleMap : ^b * _ -> ^t) (b, a))
        call_2 (Unchecked.defaultof<Tuple>, x) f

type IOption<'T> =
    abstract member Value : 'T

module Something = 
    let inline tupleMap f x = Tuple.Map f x

    let inline addOptionValues< ^value, ^options, ^values, 'item when 
                                  'item :> IOption< ^value>
                                  and (Tuple or ^options) : (static member TupleMap : ^options * Tuple -> (('item -> ^value) -> ^values))>
                                  (addUp : ^values -> ^value, sourceOptions : ^options) =
        let getValue (i : 'item) = i.Value
        let allValues : ^values = tupleMap getValue sourceOptions
        let result : ^value = addUp allValues
        result

The compiler is definitely printing the constraint wrongly although only slightly.

cc @cartermp can you rename the bug report?

Makes sense now I can see it :-)

yeah that was a tricky one but the compiler is very right about complaining :-)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vasily-kirichenko picture vasily-kirichenko  路  3Comments

ctaggart picture ctaggart  路  3Comments

smoothdeveloper picture smoothdeveloper  路  3Comments

mrakgr picture mrakgr  路  3Comments

drguildo picture drguildo  路  3Comments