Deprecate Foldable for Either

Anthony Clayden anthony_clayden at clear.net.nz
Thu Mar 23 10:18:32 UTC 2017


> On Thu Mar 2 16:30:21 UTC 2017 Henning Thielemann wrote:

>> On Thu, 2 Mar 2017, Andreas Abel wrote:

>> Today a student came to me wondering why a certain
function 
>> produced a regular result, where he had expected an
error.  
>> Turned out he had used `concat`, but not on a lists of
lists
>> as he had thought, but on a lists of `Either a [b]`.

> That is, he did (concat (xs :: [Either a [b]]))? 
> Does GHC actually accept that?
> If at all, it would not have to do with Foldable.

Good questions Henning. They've got swamped.
I found Andreas' description a bit unclear.

We have:
    concat :: Foldable t => t [a] -> [a]

So the `concat` you put above would give an error.

To get a result, the student must have put
    (concat (xs :: Either a [b]))
And got result either `[]` from (Left _)
or a genuine List from (Right ys).

Either way, I'd be grumpy: this hasn't and couldn't
concatenate anything.

Two thoughts:
1) The FTP hasn't done a very thorough job.
     Why is `[a]` hard-coded in the signature for concat?
     I would expect anything specific to Lists to be
genericised:
    concat :: (Foldable t1, Foldable t2) => t1 (t2 a) -> t2
a

2) It's obvious why FTP didn't go that far:
     (concat (xs :: [Either a [b]])) -- as you speculated --
would be daft.
     concat only applies for structures that can be
concatenated.
     But that surely includes more than Lists(?)
     So this is essentially the same complaint as for
`length`:
     Why have an instance of Foldable which always returns
length 1?
     (Or for some instances returns length 0 or 1.)

`concat` and `length` should not be in Foldable.
They should be in a separate class `Consable` (say),
which would be a sub-class of Foldable.

Note that `length` used not to be in Foldable.
`concat` was, but restricted to Lists, as now.

If there's a need for a method in Foldable
to return 1 for a tuple, or 0..1 for Maybe/Either,
don't call it `length`, call it `cardinality` (say).
(This is the same approach as for separate `map`, `fmap`,
`foldMap`.)

That isn't breaking genericity/polymorphism/library
rationalisation,
`length` was never previously available for non-List
Foldables.
So no code could have been using it.
`concat` was always in the wrong place,
but Foldable (when it was a bit of a rag-bag) used to be
good enough.


AntC


More information about the Libraries mailing list