ghc-plugin-non-empty icon indicating copy to clipboard operation
ghc-plugin-non-empty copied to clipboard

Support list concatenation

Open german1608 opened this issue 3 years ago • 3 comments

Currently, declarations such as:

nonEmptyListIntConcat :: NonEmpty Int
nonEmptyListIntConcat = [1] ++ []

...fail even though the list is not really empty.

The trick part is going to be add support for multiple concatenation:

nonEmptyListIntConcat' :: NonEmpty Int
nonEmptyListIntConcat' = [] ++ [2] ++ [] ++ [3, 4]

as this should desugar to something roughly like this:

nonEmptyListIntConcat' :: NonEmpty Int
nonEmptyListIntConcat' = 2 :| [3, 4]

german1608 avatar Oct 18 '22 23:10 german1608

@german1608 Thanks for the idea!

I'm not sure this requires support from the plugin 🤔 You can use <> instead of ++ to append NonEmpty (which is the same number of characters and even available from Prelude). And I don't see lots of benefits in adding empty lists.

So, in my vision, this

nonEmptyListIntConcat' :: NonEmpty Int
nonEmptyListIntConcat' = [] ++ [2] ++ [] ++ [3, 4]

becomes this:

nonEmptyListIntConcat' :: NonEmpty Int
nonEmptyListIntConcat' = [2] <> [3, 4]

And I believe this is already supported by the plugin.

Do you have a different use case on your mind?

chshersh avatar Oct 19 '22 11:10 chshersh

I forgot about the <> operator. And indeed you're right. The following will work fine:

l :: NonEmpty Int
l = [1] <> [2]

But once you add an empty list somewhere in the expression, it doesn't compile:

l :: NonEmpty Int
l = [1] <> [2] <> []

I don't really think somebody will create an expression like that (who really knows)

Nevertheless, adding support for ++ when <> works fine might not be really worth it.

Something we could do though is add tests for things we can and can't do with <>, and perhaps document them.

german1608 avatar Oct 19 '22 19:10 german1608

I don't really think somebody will create an expression like that (who really knows)

I agree, there's no much need in supporting this. I can see the benefit in having nicer syntax for something like this:

l = [1, 2, 3] <> [4 | isSomeBoolValue]

So people don't need to write it awkwardly. But I imagine this would require a lot of work to support and I currently don't have the capacity for this.

What can be done, indeed, as you mentioned:

  • Improve error message when trying to convert an empty list
  • Add a test for using <> just to make sure it works
  • Document this usage example

chshersh avatar Oct 20 '22 09:10 chshersh