Proposal: Applicative => Monad: Call for consensus

Bas van Dijk v.dijk.bas at gmail.com
Sat Jan 8 00:19:57 CET 2011


On Fri, Jan 7, 2011 at 11:59 AM, Henning Thielemann
<lemming at henning-thielemann.de> wrote:
> Bas van Dijk schrieb:
>> class Applicative m => Monad m  where
>>     (>>=) :: forall a b. m a -> (a -> m b) -> m b
>
> Is the explicit 'forall' intended?

The explicit 'forall' was already there with the following comment:

-- Explicit for-alls so that we know what order to
-- give type arguments when desugaring

>> 2) Make 'join' a method of Monad.
>
> Is there a need for it?

Like others in this thread have shown, I believe it allows you to
write shorter/simpler/elegant Monad instances.

However, maybe it's better to move this to its own proposal so we can
focus our attention to the proposed hierarchy.

>> 3) Export Applicative(pure, (<*>), (*>), (<*)) from the Prelude.
>> (Maybe we shouldn't export the (*>) and (<*) methods.)
>
> No, please avoid that. Importing Applicative explicitly is completely ok
> for me.

Currently you can define a Functor and Monad instance without
importing anything (because they are both exported by the Prelude).
When Applicative becomes a superclass of Monad users _have_ to write
an instance for it. I think it would be weird and irritating that you
can define the Functor and Monad instances without importing anything
but you do have to import Applicative. I would rather either export
all the three classes from the Prelude or export none of them.

> I use (<*>) already for scalar product in NumericPrelude. For me
> it looks like a commutative operator, which Applicative.<*> is not. The
> existence of (<*>) in Applicative module is ok for me, but I do not want
> name clashes with it when automatically imported by Prelude.

Personally, I'm not the biggest fan of the '<*>' symbol either. I
would rather like something which doesn't look commutative and
features a '$' somewhere to indicate its "applicative" nature.
However, I don't think we should be proposing name changes in this
proposal.

Is there a possibility you can rename your scalar product combinator
to something else? '.*.' maybe?

> If at all, Functor stuff should be moved from Control.Applicative and
> Control.Monad to a new module Control.Functor (and could be re-exported
> by Control.Applicative and Control.Monad for compatibility reasons).
> Then fmap could be renamed to 'map' and used as F.map (using "import
> qualified Control.Functor as F"). All those infix operators for Monad
> and Functor are not so important for me to be imported automatically
> from Prelude. Thus I would not like to move Applicative in this direction.
>
>> 4) Also export the join method from the Prelude.
>
> no please, as above

Fair enough.

>> 5) Add Applicative instances for all monads in base.
>
> +1
>
>> 6) Add a Monad instance for ((,) a): (There are already Functor and
>> Applicative instances for it.)
>
> That is, a Writer instance?
>
> I am uncertain about it, because using it may hide a bug. So far I am
> happy with Writer from transformers package. Using Writer explicitly
> shows everybody, what I am doing and that I do it intentionally.

Yes, I think I need to remove this from the patch. However, I do
believe we either need to have both Functor, Applicative and Monad
instances or none of them. It feels weird to only have Functor and
Applicative instances.

>> The patch for ghc simply adds Applicative instances for all monads in
>> ghc. Also included in the ghc patch bundle are some refactoring
>> patches that will make the transition easier:
>>
>> * Added (<>) = mappend to compiler/utils/Util.hs.
>> * Add a Monoid instance for AGraph and remove the <*> splice operator.
>> Instead of <*>, the (<>) = mappend operator is now used to splice AGraphs.
>> This change is needed because <*> clashes with the Applicative apply
>> operator <*>, which is probably going to be exported from the Prelude
>> when the new Monad hierarchy is going through. (Simply hiding <*> from
>> the Prelude is also possible of course. However, I think this makes
>> things easier to understand)
>
> For me this is another argument against automatic import of (<*>).
>
>> * Make SDoc an abstract newtype and add a Monoid instance for it.
>> The (<>) combinator of SDocs is removed and replaced by the more
>> general (<>) = mappend combinator from Util.
>
> An infix operator for monoids would be nice, indeed. Why not use
> something that resembles (++), which is the "mappend" for lists? I am
> uncertain. Maybe something containing '+' looks too commutative. :-) But
> '<>' looks too much like 'not equal' in other languages.

I choose '<>' because it was already the append for SDocs. I too like
something featuring '++'. Or maybe '++' itself.

Regards,

Bas



More information about the Libraries mailing list