Skip to content

Improve internal type signature #623

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Conversation

fxdmhtt
Copy link

@fxdmhtt fxdmhtt commented Jun 5, 2025

The signature of GroupBy.Invoke function is abnormal, which causes the secondary encapsulated 'Collection<'T> type to be incorrectly identified (identified as Id<'T>).

Refer to ChunkBy.Invoke, this should be just a typo.

@@ -305,7 +305,7 @@ type GroupBy =
static member GroupBy (x: list<'T>, f: 'T->'Key, _: list<'Key*list<'T>>, [<Optional>]_impl: GroupBy) = Seq.groupBy f x |> Seq.map (fun (x, y) -> x, Seq.toList y) |> Seq.toList
static member GroupBy (x: 'T [] , f: 'T->'Key, _: ('Key*('T [])) [] , [<Optional>]_impl: GroupBy) = Seq.groupBy f x |> Seq.map (fun (x, y) -> x, Seq.toArray y) |> Seq.toArray

static member inline Invoke (projection: 'T->'Key) (source: '``C<'T>``) : '``C<'Key * 'C<'T>>`` =
static member inline Invoke (projection: 'T->'Key) (source: '``Collection<'T>``) : '``Collection<'Key * 'Collection<'T>>`` =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note the ticks in the type signature. The C here is more for documentation rather than an actual type

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it won't change any behavior. Not even a public signature.
But it reads better, so we can accept the PR as a code readability improvement.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sure, I’m wondering if @fxdmhtt has some issue with code? Something that does not compile?

@gusty
Copy link
Member

gusty commented Jun 5, 2025

The signature of GroupBy.Invoke function is abnormal, which causes the secondary encapsulated 'Collection<'T> type to be incorrectly identified (identified as Id<'T>).

@fxdmhtt please create an issue for this. with a small repro, then we can help and reference eventually a PR that will address it.

We'll accept this PR but it's unlikely that it will solve any issue.

@gusty gusty changed the title Update Collection.fs Improve internal type signature Jun 5, 2025
@fxdmhtt
Copy link
Author

fxdmhtt commented Jun 5, 2025

I have seen your reply and I completely agree with what you said.

I think it is more of my own problem and I didn't want to bother you about it.

Please allow me to extract a minimal reproducible code tomorrow. Thank you very much!

@fxdmhtt
Copy link
Author

fxdmhtt commented Jun 6, 2025

Thank you very much.

The minimal example code is as follows:

open FSharpPlus

let inline groupby (key: 'T -> 'Key when 'Key : equality) (sequence: '``Collection<'T>``) : Map<'Key, '``Collection<'T>``> =
    sequence
    |> groupBy key
    |> Map.ofSeq

I will get a wavy line error on groupBy:

The type 'Internals.Id<'Key * Internals.Id<'T>>' is not compatible with the type '('Key * 'Collection<'T>) seq'.

This code doesn't really mean anything, I'm just more familiar with Python so I'm trying to simulate the behavior of the Toolz package. This is a toy.

Specifically, I'm trying to wrap the generic groupBy as Toolz.groupby

I'm a beginner in F# and don't know if this problem is caused by FSharpPlus, but as of now, I really don't have any idea to solve this compilation error.

FSharpPlus: 1.7.0
OS: Windows 10
.NET: 9.0

Thanks again!

Additional information:

I found that when the function signature is changed to the following:

let inline groupby (key: 'T -> 'Key when 'Key : equality) (sequence: '``Collection<'T>``) =
    sequence
    |> groupBy key
    |> Map.ofSeq

that is, the signature of the function output is removed.

the compilation error will disappear, but the type inference will not be able to recognize the real information.

The Ionide plugin infers:

val inline groupby:
   key     : ('T -> 'Key) ->
   sequence: 'Collection<'T> (requires static member GroupBy )
          -> Map<'b,'c> (requires comparison)

I don't know how to modify

@gusty
Copy link
Member

gusty commented Jun 9, 2025

This looks like a bug/limitation.

I mean, your repro code goes a bit far into the limits of this library / F# type inference limitations.

Having said that, at first sight it looks easy to solve. I can give it a try.

@gusty
Copy link
Member

gusty commented Jun 10, 2025

@fxdmhtt I managed to fix your issue here #633

For this PR, could you also change the other signatures in this files the same way?
I think there is another C<'T> somewhere.

@fxdmhtt
Copy link
Author

fxdmhtt commented Jun 11, 2025

There are many C<'T> in the code, but the only lonely C<'T> is in the GroupBy function. I don't know which "another" you are referring to.

Have you considered replacing all C<'T> in batches?

Copy link
Member

@gusty gusty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See in Distinct, DistinctBy, Rev, and all Sort related Invokables have also the abbreviated C<T>` type signature.

Please apply the same change to them, so we can merge this.

@gusty
Copy link
Member

gusty commented Jun 11, 2025

There are many C<'T> in the code, but the only lonely C<'T> is in the GroupBy function. I don't know which "another" you are referring to.

See my review, or just do a find C<'T>.

Have you considered replacing all C<'T> in batches?

I rarely do these kind of PRs that only impact code readability, I'm not saying it's bad, it's just that since I have limited time I prefer to focus myself in solving functionality issues. So, it's good to have collaborators who take care of code uniformity. It definitely helps in the long run.

…ve clarity and consistency in type references for collection operations. Enhances readability and aligns with naming conventions.
@fxdmhtt
Copy link
Author

fxdmhtt commented Jun 11, 2025

There are many C<'T> in the code, but the only lonely C<'T> is in the GroupBy function. I don't know which "another" you are referring to.

See my review, or just do a find C<'T>.

Have you considered replacing all C<'T> in batches?

I rarely do these kind of PRs that only impact code readability, I'm not saying it's bad, it's just that since I have limited time I prefer to focus myself in solving functionality issues. So, it's good to have collaborators who take care of code uniformity. It definitely helps in the long run.

Please review the patch

Copy link
Member

@gusty gusty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK from my side, let's see if CI agree as well ;)

@fxdmhtt
Copy link
Author

fxdmhtt commented Jun 11, 2025

Sorry. I saw the CI error, but I don't have the ability to fix it.

In fact, I raised this issue because I encountered difficulties in using F# type inference.

I need your help.

Thank you very much.

@gusty
Copy link
Member

gusty commented Jun 11, 2025

No worries. I will fix it and merge it.
Thanks !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants