# Diagonalization/ dupe for monads and tuples?

Markus Läll markus.l2ll at gmail.com
Fri Sep 25 12:54:30 UTC 2020

```How about `eitherId` for the `Either a a -> a`? I.e one usually does
`either id id` to extract either value.

`fromEither` isn't a bad idea, but it's long.

On Wed, Sep 23, 2020 at 3:49 PM Carter Schonwald <carter.schonwald at gmail.com>
wrote:

> Rob,
> 1) your foldEither is way better and I love it.
>
> 2) this is a way more pleasing Avenue of design for the tuple and either
> combinators ! Thank you for sharing this great little exposition.
>
> On Wed, Sep 23, 2020 at 8:20 AM Rob Rix via Libraries <
>
>> TL;DR: maybe we can think of this as combining disjoint empty & non-empty
>> cases of folds.
>>
>> Every time I’ve wanted to define something like this I’ve found myself
>> dissatisfied because of this asymmetry.
>>
>> Looking at it from another angle, I frequently encounter a vaguely
>> similar situation with folds: given some collection which can be empty or
>> non-, I want to fold over it with a function if non-empty, or return a
>> default value if empty:
>>
>> foldr1OrDefault :: Foldable t => (a -> a -> a) -> a -> t a -> a
>> foldr1OrDefault f z t
>>   | null t    = z
>>   | otherwise = foldr1 f t
>>
>>
>> This is a bit like Control.Lens.Fold.foldBy in lens, except that the
>> combining function f does not receive z at any point. Quite useful when you
>> have a Semigroup but not a Monoid, or when you otherwise want to treat the
>> empty case specially.
>>
>> fromMaybe is a special case of this function, without the conceit of
>> pretending that Maybe can hold multiple values. I’ve sometimes involved
>> Maybe in this construction for just that reason when e.g. a is a Semigroup:
>>
>> fold1Maybe :: (Foldable t, Semigroup a) => t a -> Maybe a
>> fold1Maybe = foldMap Just
>>
>> fold1OrDefault :: (Foldable t, Semigroup a) => a -> t a -> a
>> fold1OrDefault z = fromMaybe z . foldMap Just
>>
>>
>> (All of these names are intentionally bad because I don’t want to propose
>> adding these functions anywhere just yet.)
>>
>> For Either (and These for that matter), a full generalization also has to
>> deal with the extra information in the null case, i.e. Either b a would
>> need (b -> a) instead of a:
>>
>> fromEither :: (b -> a) -> Either b a -> a
>> fromEither f = either f id
>>
>>
>> I’m surprised about once every six months that this doesn’t exist (and
>> then surprised again when consulting the types that fromLeft/fromRight
>> aren’t either this *or* analogous to fromJust).
>>
>> All of which is to say, I think I would prefer to have the generality of
>> this fromEither to the a -> Either a a -> a version, but it’d be nice to
>> figure out a way to see it as a fold, too. Maybe the Bifoldable1 instance
>> for Either has something to contribute here?
>>
>> Rob
>>
>> On Sep 17, 2020, at 1:13 PM, Philip Hazelden <philip.hazelden at gmail.com>
>> wrote:
>>
>> On Thu, Sep 17, 2020 at 5:59 PM Jon Purdy <evincarofautumn at gmail.com>
>> wrote:
>>
>>> { fromMaybe, fromLeft, fromRight, fromEither, fromThese, fromDynamic, …
>>> } extracts “the” value out of a { Maybe, These, Dynamic, … } with a
>>> suitable default if “it” isn’t present.
>>>
>>
>> Hm. A weird thing about fromEither compared to (I think) all the rest of
>> these, is that the type of the Either isn't fully general. That is,
>> fromLeft and fromRight take an `Either a b`; fromThese takes a `These a b`.
>> But the proposed `fromEither` takes an `Either a a`.
>>
>> This maybe isn't a big deal. Just seemed worth noting.
>>
>>
>> _______________________________________________
>> Libraries mailing list
>>
>>
>> _______________________________________________
>>
>> Libraries mailing list
>>
>>
>>
>> _______________________________________________
> Libraries mailing list