fsharp / fslang-suggestions

The place to make suggestions, discuss and vote on F# language and core library features
345 stars 21 forks source link

[SRTP] Allow overrides in the modern SRTP syntax #1318

Open xperiandri opened 1 year ago

xperiandri commented 1 year ago

I propose we allow overrides in modern SRTP syntax as the code below does not work

Only the last Slice: int -> 'c method override condition is resolved but no one before the last

open System.Runtime.CompilerServices

[<Extension>]
type SliceExtensions =
    [<Extension>]
    static member inline GetSlice<'c
            when 'c : (member Slice: int * int -> 'c)
            and  'c : (member Slice: int -> 'c)
            and  'c : (member Length: int)>
        (source: 'c, from: int option, ``to``: int option) =

        match from, ``to`` with
        | Some from, Some ``to`` -> source.Slice(from, ``to`` + 1 - from)
        | Some from, None -> source.Slice(from)
        | None, Some ``to`` -> source.Slice(0, ``to`` + 1)
        | None, None -> source.Slice(0, 1)

open System.Collections.Immutable

let arr = seq { 0; 1; 2; 3; 4 } |> ImmutableArray.CreateRange
arr[..2]

If you swap

            when 'c : (member Slice: int * int -> 'c)
            and  'c : (member Slice: int -> 'c)

as

            when 'c : (member Slice: int -> 'c)
            and  'c : (member Slice: int * int -> 'c)

the compiler will use the the second one again but not both

The existing way of approaching this problem in F# is to use old SRTP syntax

Pros and Cons

The advantages of making this adjustment to F# are code amount reduction

The disadvantages of making this adjustment to F# are not exist

Extra information

Estimated cost (XS, S, M, L, XL, XXL): S

Related suggestions:

Affidavit (please submit!)

Please tick these items by placing a cross in the box:

Please tick all that apply:

For Readers

If you would like to see this issue implemented, please click the :+1: emoji on this issue. These counts are used to generally order the suggestions by engagement.

xperiandri commented 1 year ago

Without SRTP overrides it works

open System.Runtime.CompilerServices

[<Extension>]
type SliceExtensions =

    [<Extension>]
    static member inline GetSlice<'c
            when 'c : (member Slice: int * int -> 'c)
            and  'c : (member Length: int)>
        (source: 'c, from: int option, ``to``: int option) =

        let from = from |> Option.defaultValue 0
        let ``to`` = ``to`` |> Option.defaultValue (source.Length - 1)
        source.Slice(from, ``to`` + 1 - from)

open System.Collections.Immutable

let arr = seq { 0; 1; 2; 3; 4 } |> ImmutableArray.CreateRange
arr[..2]
nodakai commented 11 months ago

It seems you're referring to "overloads"? https://stackoverflow.com/questions/673721/overloading-and-overriding

I ended up posting a duplicate as issue #1342, as this didn't come up in my search.

Also, based on my example, it appears this issue arises with or without the new SRTP syntax.

I recommend revising the title for better accuracy, and I can then close mine.