Opened 5 years ago

Last modified 2 years ago

#9588 new task

Add `MonadPlus (Either e)` and `Alternative (Either e)` instances

Reported by: hvr Owned by: hvr
Priority: normal Milestone:
Component: Core Libraries Version:
Keywords: report-impact Cc: simonpj, hvr, ekmett, core-libraries-committee@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: #10755 #12160 Differential Rev(s):
Wiki Page:

Description (last modified by ekmett)

The following 2 instances are currently Orphans in transformers but could be defined in base without instead:

instance Error e => MonadPlus (Either e)
instance Error e => Alterantive (Either e)

This would, however, require us to move Error from transformers into base, which may be a controversial move.

Change History (13)

comment:1 Changed 5 years ago by hvr

I'm hitting a problem while trying to implement this.

While the IO instances are rather straightforward (and btw, there's also an Alternative IO instance defined in transformers):

instance MonadPlus IO where
    mzero       = ioError (userError "mzero")
    m `mplus` n = m `catchIOError` \ _ -> n

instance Alternative IO where
    empty = mzero
    (<|>) = mplus

The instances for Either, however, depend on an Error class in transformers to produce an empty/mzero value:

instance (Error e) => Alternative (Either e) where
    empty        = Left noMsg
    Left _ <|> n = n
    m      <|> _ = m

instance (Error e) => MonadPlus (Either e) where
    mzero            = Left noMsg
    Left _ `mplus` n = n
    m      `mplus` _ = m

how shall this issue be resolved?

comment:2 Changed 5 years ago by ekmett

The IO case is easy and should definitely go in. That one is a no-brainer.

However, looking at it, I'm rather uncomfortable about the notion of moving the rather ad hoc Error class into base. Nobody likes it.

Perhaps the fate of the Either instance should go back out to the libraries mailing list to try to round up ideas.

We could

a.) Leave it where it is b.) Bring Error into base. c.) Switch it to Monoid, which is sadly too big and may break some usecases where noMsg /= mempty holds now. d.) Bring Default into base, which IIRC was already rejected by the libraries@ list, and use that instead. e.) Figure out something else.

comment:3 Changed 5 years ago by thoughtpolice

Component: libraries/baseCore Libraries

Moving over to new owning component 'Core Libraries'.

comment:4 Changed 5 years ago by thoughtpolice

Milestone: 7.10.17.12.1

Moving to 7.12.1 milestone; if you feel this is an error and should be addressed sooner, please move it back to the 7.10.1 milestone.

comment:5 Changed 5 years ago by hvr

Cc: core-libraries-committee@… added
Keywords: report-impact added

comment:6 Changed 5 years ago by ekmett

We should at least split this up into the easy and the hard cases and bite off the IO instances for now, and we can explicitly punt on the Either e case until someone comes up with a better idea.

comment:7 Changed 4 years ago by hvr

Description: modified (diff)
Milestone: 7.12.1
Summary: Add `MonadPlus {IO,Either e}` and `Alternative (Either e)` instancesAdd `MonadPlus (Either e)` and `Alternative (Either e)` instances

I've split off the easy doable part into #10755

comment:8 Changed 4 years ago by ekmett

Description: modified (diff)

comment:9 Changed 4 years ago by ekmett

I've updated the description to note that the CLC approved the IO instances unconditionally, but expressed reservations about the Either instances.

comment:10 Changed 3 years ago by Iceland_jack

comment:11 Changed 2 years ago by Iceland_jack

intended?

$ ghci-8.0.1
GHCi, version 8.0.1: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /apps/strats/.ghci
> import Data.Foldable
> import Control.Applicative
> import Control.Monad.Trans.Error

<interactive>:1:1: warning: [-Wdeprecations]
    Module Control.Monad.Trans.Error is deprecated:
      Use Control.Monad.Trans.Except instead
> Left "A" <|> Left "B"
Left "B"
> asum [Left "A", Left "B"]
Left ""

comment:12 Changed 2 years ago by ekmett

Sadly.

The current Error based instance in transformers is somewhat lacking in this and other regards.

comment:13 in reply to:  12 Changed 2 years ago by Iceland_jack

Replying to ekmett:

Sadly.

The current Error based instance in transformers is somewhat lacking in this and other regards.

I mindlessly applied that and it broke a parser in our code :)

Note: See TracTickets for help on using tickets.