Skip to content

FS0193 when constraining a type parameter by different instanciations of the same interface #12814

Description

@SchlenkR

Constraining a type parameter by different generic instanciations of the same interface results in an FS0193 error:

type IGet<'a> =
    abstract member GetValue : unit -> 'a

type T() =
    member this.DoIt<'a
        when 'a :> IGet<int>
        and  'a :> IGet<float> // FS0193: Type ''a' is not compatible with type 'IGet<float>'
        >
        (a: 'a) =
            let intValue = (a :> IGet<int>).GetValue()
            let floatValue = (a :> IGet<float>).GetValue()
            (float intValue) + floatValue

Expected behavior

Constraining in the provided way should be possible.

Actual behavior

Constraining results in an error: FS0193: Type ''a' is not compatible with type 'IGet<float>'

Known workarounds

// Not working (FS0193):
// ---------------------
// type IGetInt = IGet<int>
// type IGetFloat = IGet<float>

// Not working (FS0193):
// ---------------------
// type IGetInt =
//     interface
//         inherit IGet<int>
//     end
// type IGetFloat =
//     interface
//         inherit IGet<float>
//     end

// Disjoint types work:
// --------------------
type IGetInt =
    abstract member GetValue : unit -> int
type IGetFloat =
    abstract member GetValue : unit -> float

type T() =
    member this.DoIt<'a
        when 'a :> IGetInt
        and  'a :> IGetFloat
        >
        (a: 'a) =
            let intValue = (a :> IGetInt).GetValue()
            let floatValue = (a :> IGetFloat).GetValue()
            (float intValue) + floatValue

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions