Split the IsList class for OverloadedLists

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Split the IsList class for OverloadedLists

Li-yao Xia-2
Hello Café,

Right now the IsList class used by the OverloadedLists extension
requires both fromList, to construct something using list syntax, and
toList, to pattern-match on something using list syntax.

So types implementing that class are expected to be isomorphic to lists.
This is a very strong restriction. In particular, this gets in the way
of implementing IsList for aeson's Value type[1], since there's no
sensible total implementation of toList.

[1]: That is a recently proposed idea
https://github.com/bos/aeson/issues/813


Proposal: split toList and fromList in two separate classes.

(And modify the OverloadedLists extension accordingly.)

Since they rely on an associated type family Item, it would be made a
standalone family.


type family Item (l :: Type) :: Type

class ToList l where
   toList :: l -> [Item l]

class FromList l where
   fromList :: [Item l] -> l
   fromListN :: Int -> [Item l] -> l


(Note: we can't just replace ToList with Foldable, because these classes
have different kinds.)


- Any objections? An obvious concern is backwards compatibility. Is that
a deal breaker? Are there other issues with this idea?

- Should that be a GHC proposal[2]?

- Has this been discussed before?

[2]: https://github.com/ghc-proposals/ghc-proposals


One alternative is to use RebindableSyntax, which already allows users
to redefine toList and fromList however they want. The issue is it might
also mess with all other kinds of syntactic sugar just enough that the
unpleasantness is not worth the trouble.

For example, if you wanted to use multiple list-like types in one
module, you would want an overloaded version of fromList/fromListN. You
either roll your own or find a suitable dependency. Either way it's
overhead you might not be willing to pay for, as opposed to something
that's already in base and Just Works.

So even with some existing workarounds in mind, the above proposal seems
a net improvement over the status quo.

Maybe some day we'll also get to take fromInteger out of Num.

Regards,
Li-yao
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: Split the IsList class for OverloadedLists

Olaf Klinke
> Hello Café,
>
> Right now the IsList class used by the OverloadedLists extension
> requires both fromList, to construct something using list syntax,
> and
> toList, to pattern-match on something using list syntax.
>
> So types implementing that class are expected to be isomorphic to
> lists.
> This is a very strong restriction. In particular, this gets in the
> way
> of implementing IsList for aeson's Value type[1], since there's no
> sensible total implementation of toList.
>
> [1]: That is a recently proposed idea
> https://github.com/bos/aeson/issues/813

For constructing values from list syntax, I can understand that only
fromList is used and Aeson's Value indeed contains lists. But if both
fromList and toList are required, I would expect that
fromList.toList=id and I can not see how that can ever be achieved with
Aeson Values.
Maybe a lightweight quasi-quoter can be syntactically almost as
convenient for construction?

MonoFoldable and MonoTraversable instances for Value might also be
helpful: MonoFoldable gives you a toList function.  

>
>
> Proposal: split toList and fromList in two separate classes.
>
> (And modify the OverloadedLists extension accordingly.)
>
> Since they rely on an associated type family Item, it would be made
> a
> standalone family.
>
>
> type family Item (l :: Type) :: Type
>
> class ToList l where
>    toList :: l -> [Item l]
>
> class FromList l where
>    fromList :: [Item l] -> l
>    fromListN :: Int -> [Item l] -> l
>
>
> (Note: we can't just replace ToList with Foldable, because these
> classes
> have different kinds.)
>
>
> - Any objections? An obvious concern is backwards compatibility. Is
> that
> a deal breaker? Are there other issues with this idea?
You would lose the pattern matching functionality, it seems.
It reminds me very much of OverloadedStrings and that is not always as
convenient as you might think. The issue is that a previously
monomorphic piece of syntax suddenly is polymorphic, so in some places
with OveroadedStrings one must provide type annotations. And that
destroys the brevity one was after.

>
> - Should that be a GHC proposal[2]?
>
> - Has this been discussed before?
>
> [2]: https://github.com/ghc-proposals/ghc-proposals
>
>
> One alternative is to use RebindableSyntax, which already allows
> users
> to redefine toList and fromList however they want. The issue is it
> might
> also mess with all other kinds of syntactic sugar just enough that
> the
> unpleasantness is not worth the trouble.
>
> For example, if you wanted to use multiple list-like types in one
> module, you would want an overloaded version of fromList/fromListN.
> You
> either roll your own or find a suitable dependency. Either way it's
> overhead you might not be willing to pay for, as opposed to
> something
> that's already in base and Just Works.
>
> So even with some existing workarounds in mind, the above proposal
> seems
> a net improvement over the status quo.
>
> Maybe some day we'll also get to take fromInteger out of Num.
>
> Regards,
> Li-yao
>

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: Split the IsList class for OverloadedLists

Henning Thielemann

On Sat, 31 Oct 2020, Olaf Klinke wrote:

>> (Note: we can't just replace ToList with Foldable, because these
>> classes have different kinds.)
>>
>>
>> - Any objections? An obvious concern is backwards compatibility. Is
>> that a deal breaker? Are there other issues with this idea?

> You would lose the pattern matching functionality, it seems.
> It reminds me very much of OverloadedStrings and that is not always as
> convenient as you might think. The issue is that a previously
> monomorphic piece of syntax suddenly is polymorphic, so in some places
> with OveroadedStrings one must provide type annotations. And that
> destroys the brevity one was after.

That's the problem.

Instead of extending syntactic sugar you can resort to plain functional
programming. Constructing a list:

    l :: [a] -> YourList a

Use like:

    l[1,2,3].

Matching a list using continuation passing:

    withList :: ([a] -> b) -> YourList a -> b

Use like in:

    func m = withList $ \(x:y:_) n -> ...
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.