[GHC] #9883: Make OverloadedLists more usable by splitting the class interface
GHC
ghc-devs at haskell.org
Tue Dec 16 12:52:06 UTC 2014
#9883: Make OverloadedLists more usable by splitting the class interface
-------------------------------------+-------------------------------------
Reporter: muesli4 | Owner:
Type: feature | Status: new
request | Milestone: ⊥
Priority: normal | Version: 7.8.3
Component: External | Keywords: overloaded lists,
Core | islist
Resolution: | Architecture: Unknown/Multiple
Operating System: | Difficulty: Moderate (less
Unknown/Multiple | than a day)
Type of failure: | Blocked By: 7495
None/Unknown | Related Tickets: #7495
Test Case: |
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
Comment (by muesli4):
Replying to [comment:6 goldfire]:
> Maybe I'm missing something basic, but why do we need classes at all
here? I propose we just desugar the list to use some functions in scope,
and if they don't type-check, that's the programmer's problem.
This sounds like something, which should be done with the RebindableSyntax
extension. Type classes are useful, because other libraries can easily
provide instances for it, without them you have to provide them via some
third party library and it seems to me that other uses are more like a
corner case. But of course I may be wrong, so I am all for usability and
convenience, without excluding special cases (as I said, these could be
introduced with the RebindableSyntax extension).
>
> Concretely, here are the 7 expression forms from OverloadedLists, and my
proposal for what they desugar to:
>
> {{{
> [] -- buildList 0 (listStart `listSep` listEnd)
> [x] -- buildList 1 (listStart `listSep` x `listSep` listEnd)
> [x,y,z] -- buildList 3 (listStart `listSep` x `listSep` y `listSep`
z `listSep` listEnd)
> [x .. ] -- enumFrom x
> [x,y ..] -- enumFromThen x y
> [x .. y] -- enumFromTo x y
> [x,y .. z] -- enumFromThenTo x y z
> }}}
>
> The `enumXXX` functions would use whatever is in scope -- not
necessarily the methods from `Enum`.
>
> For regular old lists, we get
>
> {{{
> buildList _ (_:elts) = elts
> listStart = undefined
> listSep = (:)
> infixr 5 `listSep`
> listEnd = []
> }}}
>
> and the `enumXXX` functions are indeed taken from the `Enum` class.
>
> Note that I included the fixity declaration for `listSep` above --
there's no reason to disallow a ''left''-associative separator. (Though,
all the elements in the list would effectively be wrapped in parentheses;
the precedence level of the `listSep` fixity declaration is meaningless in
the desugaring.)
I like what you could achieve with it, but I don't like how you do it:
* The use of {{{undefined}}} seems like a hack to make the types work.
* Can you provide some use cases where different associativity is an
advantage?
* I don't like to use operator syntax here.
* Are you able to give definitions for these functions, such that we
could use the list syntax for different types in the same module?
Let's say heterogenous lists (was that the intention?) and normal
lists.
> To me, this seems maximally flexible.
>
> With pattern synonyms, we could mimc this behavior in patterns.
>
> {{{
> [] -- MatchList 0 (ListStart `ListSep` ListEnd)
> [x] -- MatchList 1 (ListStart `ListSep` x `ListSep` ListEnd)
> [x,y,z] -- MatchList 3 (ListStart `ListSep` x `ListSep` y `ListSep`
z `ListSep` ListEnd)
> }}}
>
> For regular old lists, we get
>
> {{{
> pattern MatchList n l <- ((\list -> (length list, undefined:list)) ->
(n, l))
> pattern ListStart <- _
> pattern ListSep h t = h : t
> infixr 5 `ListSep`
> pattern ListEnd = []
> }}}
>
> The construction for `MatchList` is painful. Improvements here are
welcome.
Can you use different types with the same pattern? The compiler should
know the length of the list, so maybe it can be expressed with a type
literal (though I have no idea how to do that).
> Sorry, @muesli4, I didn't mean to steal your thunder here! I hope you
don't mind the debate. :)
Of course, that was the reason I started the ticket. I appreciate your
contribution, but I think it goes a bit over the top, my proposal was just
a slight change in an already existing extension. And I don't know whether
you can provide the same functionality, which currently exists.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9883#comment:9>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list