"Nothing" uses the same memory slot no matter how many times it's used, but "Left ()" will more than likely create a new object every time, or at the very least one for each module where it's used.

Eq and Ord instances get slightly slower because they have to compare () with () every time they receive a pair of Lefts.

Where you would pass "x" into the "maybe" deconstructor function, now you would have to pass "const x" to "either", which again uses more memory and (more importantly) more cognitive space.

We have the problem other people have mentioned where FlexibleInstances or TypeFamilies/GADTs have to be used to define instances for Either ().

However, the biggest problem is that Maybe is not actually isomorphic to Either () in a lazy language like Haskell. Maybe has

* Nothing
* Just x

However, Either () has

* Left ()
* Right x
* Left undefined

And that final value causes infinite problems, particularly when you pass it to other functions which handle strictness on the Left argument differently. Is the Eq () instance strict or lazy in its arguments? I honestly would not be able to tell you without firing up an instance of GHCi. I've seen different libraries which define singleton objects define it in different ways.

On Fri, May 29, 2020, 05:40 Henning Thielemann <lemming@henning-thielemann.de> wrote:

On Fri, 29 May 2020, Wiebe-Marten Wijnja wrote:

> Greetings, everyone!
>
> Recently I was involved in a discussion on the new ML-style language
> 'gleam'.
>
> Gleam has for quite a while now only had an `Either a b` type,
> with all functions that in Haskell one would use a `Maybe a` for,
> working on an `Either a ()` instead.

In Haskell `Maybe a` is more similar to `Either () a` than `Either a ()`.

Either has one more redirection on the Left case. You can have both `Left
undefined` and `Left ()` whereas Maybe can only have `Nothing`. I hardly
think that people actually make use of this difference, though.

Btw. from a software engineering point I'd prefer not to use Either for
both exception handling with an according Monad and for cases where you
just want to handle values of two possible types. I'd define an Except
type for the exception usage.

Could we remove Maybe in favor of Either? It would make some instances
non-Haskell-98. E.g.

   instance C Maybe where

is Haskell 98, but

   instance C (Either ()) where

needs FlexibleInstances and

   instance (a ~ ()) => C (Either a) where

needs TypeFamilies.

Unless you find out that you can define a more general instance like

   instance (Super a) => C (Either a) where

.
_______________________________________________
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.