haskell / core-libraries-committee

95 stars 15 forks source link

Re-export IsList class from a friendlier module #54

Closed TeofilC closed 2 years ago

TeofilC commented 2 years ago

Hoogle tells me that the IsList class is only exported from GHC.Exts in base. I think this class is quite useful and it would be nice to make it available from a non-internal module.

A bunch of prelude replacement packages seem to re-export it from more friendly modules so there seems to be a desire for this.

I'd recommend re-exporting IsList from Prelude or Data.List. I think that's the two modules where it makes most sense.

TeofilC commented 2 years ago

I've given this a bit more thought. And I've noticed that both Foldable and IsList have a toList method. Furthermore differences in design preclude making Foldable a superclass of IsList (at least afaict).

Given this I'm refining my proposals to re-exporting IsList from a new module called Data.IsList. This would minimize the risk of ambiguity while still exporting IsList from a less internal module, albeit a less discoverable one than I originally suggested.

mixphix commented 2 years ago

I'm quite fond of the IsList typeclass -- I (ab)use it in my Advent of Code solutions to convert between container types! -- but from my understanding it's designed for the implementation of -XOverloadedLists. I'm hesitant to expose this class more prominently in base because of its intent as a "library" class rather than an "application" class; but, if there's a strong desire in the community to use IsList as a handy list-conversion typeclass, then I'll support it.

treeowl commented 2 years ago

If it's to be a more libraryish thing, I think it would be nice to add more sequence operations. cons, viewl, snoc, viewr, append, reverseOntoL, reverseOntoR, splitAt, spanl, spanr, takeWhileL, takeWhileR, dropWhileL, dropWhileR, foldMappish, foldMappish', inits, tails.

mixphix commented 2 years ago

If it's to be a more libraryish thing, I think it would be nice to add more sequence operations. cons, viewl, snoc, viewr, append, reverseOntoL, reverseOntoR, splitAt, spanl, spanr, takeWhileL, takeWhileR, dropWhileL, dropWhileR, foldMappish, foldMappish', inits, tails.

Do you mean as class methods? These would all have varying complexities for different container types. It would be a lesson for the user to choose the right data structure for the task at hand; as it is in many other languages. A common interface for "sequences" -- separately from things that are Foldable -- would dramatically reduce namespace clashing, at the cost of hiding the implementation details under an instance declaration.

treeowl commented 2 years ago

@cigsender, once you have toList and fromList, you can implement the rest, but they'll all be inefficient for types that aren't wrappers around []. Not knowing the performance is unfortunate for sure. One option would be a batch of associated types: IsConsFast, IsSnocFast, etc., so you can force a type error (or, soon, a warning!) if the selected type doesn't meet your needs.

mixphix commented 2 years ago

Having the methods you listed (among others) as class methods would allow for efficient overrides where possible. Associated types such as IsConsFast are IMO an ugly solution to the real problem, which is that Haddock will not display documentation for method implementations.

treeowl commented 2 years ago

No, they solve a different problem. Both problems are important.

  1. Documentation should be able to offer method implementation info so users can select an appropriate instance.
  2. Users should be able to ensure that they will not unthinkingly use an inefficient method without a warning to make sure they've considered the consequences in context.
Bodigrim commented 2 years ago

Hoogle tells me that the IsList class is only exported from GHC.Exts in base. I think this class is quite useful and it would be nice to make it available from a non-internal module... I'd recommend re-exporting IsList from Prelude or Data.List. I think that's the two modules where it makes most sense.

The reason is that IsList is not supposed to be used outside of {-# LANGUAGE OverloadedLists #-}, which is a GHC extension. This makes GHC.Exts an appropriate place for it, at least in theory, but I agree that it does not mix well with other contents there. That said, I would not expose it from Prelude or Data.List. How about GHC.IsList?

TeofilC commented 2 years ago

How about GHC.IsList?

That sounds good to me.

Bodigrim commented 2 years ago

@TeofilC if you'd like to move this forward, please put up a draft MR.

TeofilC commented 2 years ago

GHC MR: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8124

Bodigrim commented 2 years ago

Dear CLC members, let's vote on https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8124, which moves class IsList outside of depths of GHC.Exts, where only a daring soul guided by experienced hand could find it, into a new shiny GHC.IsList. CC @cigsender @tomjaguarpaw @emilypi @chessai @cgibbard


+1 from me.

mixphix commented 2 years ago

+1

emilypi commented 2 years ago

Makes sense +1

tomjaguarpaw commented 2 years ago

+1

Seems a more appropriate place and it is re-exported from GHC.Exts for backwards compatibility.

Bodigrim commented 2 years ago

With 4 votes in favor out of 6 possible, the proposal is approved by CLC, thanks.

chshersh commented 1 year ago

I'm trying to summarise the state of this proposal as part of my volunteering effort to track the progress of all approved CLC proposals.

Field Value
Authors @TeofilC
Status merged
base version 4.17.0.0
Merge Request (MR) https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8124
Blocked by nothing
CHANGELOG entry present
Migration guide not needed

Please, let me know if you find any mistakes 🙂