Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
243 messages Options
1234 ... 13
Reply | Threaded
Open this post in threaded view
|

Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Herbert Valerio Riedel
Hello *,

Concluding AMP and MFP, We (David and I) proudly present you the final
installment of the Monad trilogy:


Monad of no `return` Proposal
=============================

TLDR: To complete the AMP, turn `Monad(return)` method into a
      top-level binding aliasing `Applicative(pure)`.


Current Situation
-----------------

With the implementation of Functor-Applicative-Monad Proposal (AMP)[1] and
(at some point) the MonadFail proposal (MFP)[2] the AMP class hierarchy
becomes


    class  Functor f  where
        fmap    :: (a -> b) -> f a -> f b


    class  Functor f => Applicative f  where
        pure    :: a -> f a
        (<*>)   :: f (a -> b) -> f a -> f b
     
        (*>)    :: f a -> f b -> f b
        u *> v  = …
     
        (<*)    :: f a -> f b -> f a
        u <* v  = …


    class  Applicative m => Monad m  where
        (>>=)   :: m a -> (a -> m b) -> m b

        return  :: a -> m a
        return  = pure
   
        (>>)    :: m a -> m b -> m b
        m >> k  = …
       

    class  Monad m => MonadFail m  where
        fail    :: String -> m a


Consequently, the `Monad` class is left with a now redundant `return`
method as a historic artifact, as there's no compelling reason to
have `pure` and `return` implemented differently.

Traditionally, `return` is often used where `pure` would suffice
today, forcing a `Monad` constraint even if a weaker `Applicative`
would have sufficed.

As a result, language extensions like `ApplicativeDo`[3] have to
rewrite `return` to weaken its `Monad m =>` constraint to
`Applicative m =>` in order to benefit existing code at the cost
of introducing magic behavior at the type level.

Finally, this redundancy becomes even more significant when viewed in
light of the renewed Haskell standardisation process[7]: The next
Haskell Report will almost certainly incorporate the AMP (and MFP)
changes, and there's no justification for the Report to retain
`return` as a method of `Monad`. A good reason would have been to
retain backward compatibility with Haskell 2010. However, as the AMP
superclass hierarchy requires `Monad` instances to be accompanied by
`Applicative` instances (which aren't part of Haskell 2010, c.f. [6]),
backward compatibility with Haskell 2010 goes out the window when it
comes to defining `Monad` instances (unless via use of `-XCPP` or
similar).  Consequently, meeting the high bar for a formal document
such as the Haskell Report demands that `Monad` shall not carry a
redundant `return` method that serves no purpose anymore. Moreover,
getting `return` out of the way is desirable to facilitate
standardising potential candidates such as the earlier mentioned
`ApplicativeDo` in the future and avoids the technical debt incurred
by keeping around this language wart.


Proposed Change
---------------

Remove `return` as a method from the `Monad` class and in its place
define a top-level binding with the weaker `Applicative` typeclass
constraint:


    -- | Legacy alias for 'pure'
    return :: Applicative f => a -> f a
    return = pure


This allows existing code using `return` to benefit from a weaker
typeclass constraint as well as cleaning the `Monad` class from a
redundant method in the post-AMP world.

A possible migration strategy is described further below.


Compatibility Considerations
----------------------------

Generalizing the type signature of a function from a `Monad`
constraint to its superclass `Applicative` doesn't cause new
type-errors in existing code.

However, moving a method to a top-level binding obviously breaks code
that assumes `return` to be a class method. Foremost, code that
defines `Monad` instances it at risk:

### Instance Definitions

Code defining `return` as part of an instance definition
breaks. However, we had the foresight to provide a default
implementation in `base-4.8` for `return` so that the following
represents a proper minimal instance definition post-AMP:


    instance Functor Foo where
        fmap g foo  = …

    instance Applicative Foo where
        pure x      = …
        a1 <*> a2   = …

    instance Monad Foo where
        m >>= f     = …

        -- NB: No mention of `return`


Consequently, it is possible to write forward-compatible instances
that are valid under this proposal starting with GHC 7.10/`base-4.8`.

Heuristically `grep`ing through Hackage source-code reveals a
non-negligible number of packages defining `Monad` instances with
explicit `return` definitions[4]. This has a comparable impact to the
AMP, and similarly will require a transition scheme aided by compiler
warnings.

### Module Import/Export Specifications

A second source of incompatibility may be due to
`import`s. Specifically module import that assert `return` to be a
method of `Monad`, e.g.:

    import Control.Monad  (Monad ((>>=), return))

or

    import Prelude hiding (Monad(..))
    import Control.Monad  (Monad(..)) as Monad

    f = Monad.return ()

The dual situation can occur when re-exporting `return` via module
export specifications.

However, given that `return` is exported by `Prelude` and the examples
above are rather artificial, we don't expect this to be a major source
of breakage in the case of `return`. In fact, a heuristic grep[5] over
Hackage source-code revealed only 21 packages affected.

### Example for writing compatible code


    instance Functor Foo where
        fmap g foo  = …

    instance Applicative Foo where
        pure x      = …
        a1 <*> a2   = …

    instance Monad Foo where
        m >>= f     = …

    #if !(MIN_VERSION_base(4,8,0))
        return = pure
    #endif


Migration Strategy
------------------

The migration strategy is straightforward:

**Phase 1** *(GHC 8.0)*: Implement new warning in GHC which gets
   triggered when `Monad` instances explicitly override the
   default `return` method implementation.

**Phase 2** *(GHC 8.2 or later)*: When we're confident that the
   majority of Hackage has reacted to the warning (with the help of
   Stackage actively pursuing maintainers to update their packages) we
   turn the `return` method into a top-level binding and remove the
   warning implemented in Phase 1 from GHC again.


Discussion period
-----------------

A discussion period of three weeks (until 2015-10-15) should be enough
to allow everyone to chime in as well as leave enough time to make the
required preparations for GHC 8.0 should this proposal pass as we hope.

----

 [1]: https://wiki.haskell.org/Functor-Applicative-Monad_Proposal
 [2]: https://wiki.haskell.org/MonadFail_Proposal
 [3]: https://ghc.haskell.org/trac/ghc/wiki/ApplicativeDo
 [4]: https://gist.github.com/hvr/b0e34463d85b58f169d9
 [5]: https://gist.github.com/hvr/afcd040783d980594883
 [6]: https://ghc.haskell.org/trac/ghc/ticket/9590
 [7]: https://mail.haskell.org/pipermail/haskell-prime/2015-September/003936.html

--

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

attachment0 (834 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

David Feuer
+1 on both the goal and the means of reaching it. That said, I suspect
the claim that "This has a comparable impact to the AMP" may be overly
optimistic. Many Monad instances were Applicative instances before
AMP, but I'd venture to guess that almost all Monad instances
currently define return explicitly.

On Thu, Sep 24, 2015 at 5:43 PM, Herbert Valerio Riedel <[hidden email]> wrote:

> Hello *,
>
> Concluding AMP and MFP, We (David and I) proudly present you the final
> installment of the Monad trilogy:
>
>
> Monad of no `return` Proposal
> =============================
>
> TLDR: To complete the AMP, turn `Monad(return)` method into a
>       top-level binding aliasing `Applicative(pure)`.
>
>
> Current Situation
> -----------------
>
> With the implementation of Functor-Applicative-Monad Proposal (AMP)[1] and
> (at some point) the MonadFail proposal (MFP)[2] the AMP class hierarchy
> becomes
>
>
>     class  Functor f  where
>         fmap    :: (a -> b) -> f a -> f b
>
>
>     class  Functor f => Applicative f  where
>         pure    :: a -> f a
>         (<*>)   :: f (a -> b) -> f a -> f b
>
>         (*>)    :: f a -> f b -> f b
>         u *> v  = …
>
>         (<*)    :: f a -> f b -> f a
>         u <* v  = …
>
>
>     class  Applicative m => Monad m  where
>         (>>=)   :: m a -> (a -> m b) -> m b
>
>         return  :: a -> m a
>         return  = pure
>
>         (>>)    :: m a -> m b -> m b
>         m >> k  = …
>
>
>     class  Monad m => MonadFail m  where
>         fail    :: String -> m a
>
>
> Consequently, the `Monad` class is left with a now redundant `return`
> method as a historic artifact, as there's no compelling reason to
> have `pure` and `return` implemented differently.
>
> Traditionally, `return` is often used where `pure` would suffice
> today, forcing a `Monad` constraint even if a weaker `Applicative`
> would have sufficed.
>
> As a result, language extensions like `ApplicativeDo`[3] have to
> rewrite `return` to weaken its `Monad m =>` constraint to
> `Applicative m =>` in order to benefit existing code at the cost
> of introducing magic behavior at the type level.
>
> Finally, this redundancy becomes even more significant when viewed in
> light of the renewed Haskell standardisation process[7]: The next
> Haskell Report will almost certainly incorporate the AMP (and MFP)
> changes, and there's no justification for the Report to retain
> `return` as a method of `Monad`. A good reason would have been to
> retain backward compatibility with Haskell 2010. However, as the AMP
> superclass hierarchy requires `Monad` instances to be accompanied by
> `Applicative` instances (which aren't part of Haskell 2010, c.f. [6]),
> backward compatibility with Haskell 2010 goes out the window when it
> comes to defining `Monad` instances (unless via use of `-XCPP` or
> similar).  Consequently, meeting the high bar for a formal document
> such as the Haskell Report demands that `Monad` shall not carry a
> redundant `return` method that serves no purpose anymore. Moreover,
> getting `return` out of the way is desirable to facilitate
> standardising potential candidates such as the earlier mentioned
> `ApplicativeDo` in the future and avoids the technical debt incurred
> by keeping around this language wart.
>
>
> Proposed Change
> ---------------
>
> Remove `return` as a method from the `Monad` class and in its place
> define a top-level binding with the weaker `Applicative` typeclass
> constraint:
>
>
>     -- | Legacy alias for 'pure'
>     return :: Applicative f => a -> f a
>     return = pure
>
>
> This allows existing code using `return` to benefit from a weaker
> typeclass constraint as well as cleaning the `Monad` class from a
> redundant method in the post-AMP world.
>
> A possible migration strategy is described further below.
>
>
> Compatibility Considerations
> ----------------------------
>
> Generalizing the type signature of a function from a `Monad`
> constraint to its superclass `Applicative` doesn't cause new
> type-errors in existing code.
>
> However, moving a method to a top-level binding obviously breaks code
> that assumes `return` to be a class method. Foremost, code that
> defines `Monad` instances it at risk:
>
> ### Instance Definitions
>
> Code defining `return` as part of an instance definition
> breaks. However, we had the foresight to provide a default
> implementation in `base-4.8` for `return` so that the following
> represents a proper minimal instance definition post-AMP:
>
>
>     instance Functor Foo where
>         fmap g foo  = …
>
>     instance Applicative Foo where
>         pure x      = …
>         a1 <*> a2   = …
>
>     instance Monad Foo where
>         m >>= f     = …
>
>         -- NB: No mention of `return`
>
>
> Consequently, it is possible to write forward-compatible instances
> that are valid under this proposal starting with GHC 7.10/`base-4.8`.
>
> Heuristically `grep`ing through Hackage source-code reveals a
> non-negligible number of packages defining `Monad` instances with
> explicit `return` definitions[4]. This has a comparable impact to the
> AMP, and similarly will require a transition scheme aided by compiler
> warnings.
>
> ### Module Import/Export Specifications
>
> A second source of incompatibility may be due to
> `import`s. Specifically module import that assert `return` to be a
> method of `Monad`, e.g.:
>
>     import Control.Monad  (Monad ((>>=), return))
>
> or
>
>     import Prelude hiding (Monad(..))
>     import Control.Monad  (Monad(..)) as Monad
>
>     f = Monad.return ()
>
> The dual situation can occur when re-exporting `return` via module
> export specifications.
>
> However, given that `return` is exported by `Prelude` and the examples
> above are rather artificial, we don't expect this to be a major source
> of breakage in the case of `return`. In fact, a heuristic grep[5] over
> Hackage source-code revealed only 21 packages affected.
>
> ### Example for writing compatible code
>
>
>     instance Functor Foo where
>         fmap g foo  = …
>
>     instance Applicative Foo where
>         pure x      = …
>         a1 <*> a2   = …
>
>     instance Monad Foo where
>         m >>= f     = …
>
>     #if !(MIN_VERSION_base(4,8,0))
>         return = pure
>     #endif
>
>
> Migration Strategy
> ------------------
>
> The migration strategy is straightforward:
>
> **Phase 1** *(GHC 8.0)*: Implement new warning in GHC which gets
>    triggered when `Monad` instances explicitly override the
>    default `return` method implementation.
>
> **Phase 2** *(GHC 8.2 or later)*: When we're confident that the
>    majority of Hackage has reacted to the warning (with the help of
>    Stackage actively pursuing maintainers to update their packages) we
>    turn the `return` method into a top-level binding and remove the
>    warning implemented in Phase 1 from GHC again.
>
>
> Discussion period
> -----------------
>
> A discussion period of three weeks (until 2015-10-15) should be enough
> to allow everyone to chime in as well as leave enough time to make the
> required preparations for GHC 8.0 should this proposal pass as we hope.
>
> ----
>
>  [1]: https://wiki.haskell.org/Functor-Applicative-Monad_Proposal
>  [2]: https://wiki.haskell.org/MonadFail_Proposal
>  [3]: https://ghc.haskell.org/trac/ghc/wiki/ApplicativeDo
>  [4]: https://gist.github.com/hvr/b0e34463d85b58f169d9
>  [5]: https://gist.github.com/hvr/afcd040783d980594883
>  [6]: https://ghc.haskell.org/trac/ghc/ticket/9590
>  [7]: https://mail.haskell.org/pipermail/haskell-prime/2015-September/003936.html
>
> --
>
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

David Luposchainsky
"That" David is very +1 on this.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

amindfv
In reply to this post by David Feuer

> El 24 sept 2015, a las 18:02, David Feuer <[hidden email]> escribió:
>
> +1 on both the goal and the means of reaching it. That said, I suspect
> the claim that "This has a comparable impact to the AMP" may be overly
> optimistic. Many Monad instances were Applicative instances before
> AMP, but I'd venture to guess that almost all Monad instances
> currently define return explicitly.
>

Right, I share this concern. This change breaks every package that defines a Monad (and comes close to turning every unmaintained package into a broken package. For what it's worth.). A couple questions:

 - Do you have any numbers (or grep heuristics) about the magnitude of breakage (esp. relative to AMP)?

 - What are the benefits of pulling "return" out instead of leaving it with the default "return = pure" and requiring the monad laws to hold? Is the rationale "since we're already willing to break things we shouldn't do half a job"?

 - Are there any (real-world) examples of people defining "pure" and "return" differently, e.g. for efficiency?

 - If we do decide to go forward with this, let's please get this in front of a wide audience asap!

Tom


>> On Thu, Sep 24, 2015 at 5:43 PM, Herbert Valerio Riedel <[hidden email]> wrote:
>> Hello *,
>>
>> Concluding AMP and MFP, We (David and I) proudly present you the final
>> installment of the Monad trilogy:
>>
>>
>> Monad of no `return` Proposal
>> =============================
>>
>> TLDR: To complete the AMP, turn `Monad(return)` method into a
>>      top-level binding aliasing `Applicative(pure)`.
>>
>>
>> Current Situation
>> -----------------
>>
>> With the implementation of Functor-Applicative-Monad Proposal (AMP)[1] and
>> (at some point) the MonadFail proposal (MFP)[2] the AMP class hierarchy
>> becomes
>>
>>
>>    class  Functor f  where
>>        fmap    :: (a -> b) -> f a -> f b
>>
>>
>>    class  Functor f => Applicative f  where
>>        pure    :: a -> f a
>>        (<*>)   :: f (a -> b) -> f a -> f b
>>
>>        (*>)    :: f a -> f b -> f b
>>        u *> v  = …
>>
>>        (<*)    :: f a -> f b -> f a
>>        u <* v  = …
>>
>>
>>    class  Applicative m => Monad m  where
>>        (>>=)   :: m a -> (a -> m b) -> m b
>>
>>        return  :: a -> m a
>>        return  = pure
>>
>>        (>>)    :: m a -> m b -> m b
>>        m >> k  = …
>>
>>
>>    class  Monad m => MonadFail m  where
>>        fail    :: String -> m a
>>
>>
>> Consequently, the `Monad` class is left with a now redundant `return`
>> method as a historic artifact, as there's no compelling reason to
>> have `pure` and `return` implemented differently.
>>
>> Traditionally, `return` is often used where `pure` would suffice
>> today, forcing a `Monad` constraint even if a weaker `Applicative`
>> would have sufficed.
>>
>> As a result, language extensions like `ApplicativeDo`[3] have to
>> rewrite `return` to weaken its `Monad m =>` constraint to
>> `Applicative m =>` in order to benefit existing code at the cost
>> of introducing magic behavior at the type level.
>>
>> Finally, this redundancy becomes even more significant when viewed in
>> light of the renewed Haskell standardisation process[7]: The next
>> Haskell Report will almost certainly incorporate the AMP (and MFP)
>> changes, and there's no justification for the Report to retain
>> `return` as a method of `Monad`. A good reason would have been to
>> retain backward compatibility with Haskell 2010. However, as the AMP
>> superclass hierarchy requires `Monad` instances to be accompanied by
>> `Applicative` instances (which aren't part of Haskell 2010, c.f. [6]),
>> backward compatibility with Haskell 2010 goes out the window when it
>> comes to defining `Monad` instances (unless via use of `-XCPP` or
>> similar).  Consequently, meeting the high bar for a formal document
>> such as the Haskell Report demands that `Monad` shall not carry a
>> redundant `return` method that serves no purpose anymore. Moreover,
>> getting `return` out of the way is desirable to facilitate
>> standardising potential candidates such as the earlier mentioned
>> `ApplicativeDo` in the future and avoids the technical debt incurred
>> by keeping around this language wart.
>>
>>
>> Proposed Change
>> ---------------
>>
>> Remove `return` as a method from the `Monad` class and in its place
>> define a top-level binding with the weaker `Applicative` typeclass
>> constraint:
>>
>>
>>    -- | Legacy alias for 'pure'
>>    return :: Applicative f => a -> f a
>>    return = pure
>>
>>
>> This allows existing code using `return` to benefit from a weaker
>> typeclass constraint as well as cleaning the `Monad` class from a
>> redundant method in the post-AMP world.
>>
>> A possible migration strategy is described further below.
>>
>>
>> Compatibility Considerations
>> ----------------------------
>>
>> Generalizing the type signature of a function from a `Monad`
>> constraint to its superclass `Applicative` doesn't cause new
>> type-errors in existing code.
>>
>> However, moving a method to a top-level binding obviously breaks code
>> that assumes `return` to be a class method. Foremost, code that
>> defines `Monad` instances it at risk:
>>
>> ### Instance Definitions
>>
>> Code defining `return` as part of an instance definition
>> breaks. However, we had the foresight to provide a default
>> implementation in `base-4.8` for `return` so that the following
>> represents a proper minimal instance definition post-AMP:
>>
>>
>>    instance Functor Foo where
>>        fmap g foo  = …
>>
>>    instance Applicative Foo where
>>        pure x      = …
>>        a1 <*> a2   = …
>>
>>    instance Monad Foo where
>>        m >>= f     = …
>>
>>        -- NB: No mention of `return`
>>
>>
>> Consequently, it is possible to write forward-compatible instances
>> that are valid under this proposal starting with GHC 7.10/`base-4.8`.
>>
>> Heuristically `grep`ing through Hackage source-code reveals a
>> non-negligible number of packages defining `Monad` instances with
>> explicit `return` definitions[4]. This has a comparable impact to the
>> AMP, and similarly will require a transition scheme aided by compiler
>> warnings.
>>
>> ### Module Import/Export Specifications
>>
>> A second source of incompatibility may be due to
>> `import`s. Specifically module import that assert `return` to be a
>> method of `Monad`, e.g.:
>>
>>    import Control.Monad  (Monad ((>>=), return))
>>
>> or
>>
>>    import Prelude hiding (Monad(..))
>>    import Control.Monad  (Monad(..)) as Monad
>>
>>    f = Monad.return ()
>>
>> The dual situation can occur when re-exporting `return` via module
>> export specifications.
>>
>> However, given that `return` is exported by `Prelude` and the examples
>> above are rather artificial, we don't expect this to be a major source
>> of breakage in the case of `return`. In fact, a heuristic grep[5] over
>> Hackage source-code revealed only 21 packages affected.
>>
>> ### Example for writing compatible code
>>
>>
>>    instance Functor Foo where
>>        fmap g foo  = …
>>
>>    instance Applicative Foo where
>>        pure x      = …
>>        a1 <*> a2   = …
>>
>>    instance Monad Foo where
>>        m >>= f     = …
>>
>>    #if !(MIN_VERSION_base(4,8,0))
>>        return = pure
>>    #endif
>>
>>
>> Migration Strategy
>> ------------------
>>
>> The migration strategy is straightforward:
>>
>> **Phase 1** *(GHC 8.0)*: Implement new warning in GHC which gets
>>   triggered when `Monad` instances explicitly override the
>>   default `return` method implementation.
>>
>> **Phase 2** *(GHC 8.2 or later)*: When we're confident that the
>>   majority of Hackage has reacted to the warning (with the help of
>>   Stackage actively pursuing maintainers to update their packages) we
>>   turn the `return` method into a top-level binding and remove the
>>   warning implemented in Phase 1 from GHC again.
>>
>>
>> Discussion period
>> -----------------
>>
>> A discussion period of three weeks (until 2015-10-15) should be enough
>> to allow everyone to chime in as well as leave enough time to make the
>> required preparations for GHC 8.0 should this proposal pass as we hope.
>>
>> ----
>>
>> [1]: https://wiki.haskell.org/Functor-Applicative-Monad_Proposal
>> [2]: https://wiki.haskell.org/MonadFail_Proposal
>> [3]: https://ghc.haskell.org/trac/ghc/wiki/ApplicativeDo
>> [4]: https://gist.github.com/hvr/b0e34463d85b58f169d9
>> [5]: https://gist.github.com/hvr/afcd040783d980594883
>> [6]: https://ghc.haskell.org/trac/ghc/ticket/9590
>> [7]: https://mail.haskell.org/pipermail/haskell-prime/2015-September/003936.html
>>
>> --
>>
>> _______________________________________________
>> Libraries mailing list
>> [hidden email]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

John Wiegley-2
In reply to this post by Herbert Valerio Riedel
>>>>> Herbert Valerio Riedel <[hidden email]> writes:

> TLDR: To complete the AMP, turn `Monad(return)` method into a
>       top-level binding aliasing `Applicative(pure)`.

Very much +1.

John
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Dan Burton
What about the derived functions in Control.Monad, such as liftM? Shall we similarly relax their constraints to Applicative and consider them "legacy"? (Did this already happen when I wasn't looking?)

On Thursday, September 24, 2015, John Wiegley <[hidden email]> wrote:
>>>>> Herbert Valerio Riedel <<a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;hvr@gnu.org&#39;)">hvr@...> writes:

> TLDR: To complete the AMP, turn `Monad(return)` method into a
>       top-level binding aliasing `Applicative(pure)`.

Very much +1.

John
_______________________________________________
Libraries mailing list
<a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;Libraries@haskell.org&#39;)">Libraries@...
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


--
-- Dan Burton

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Mario Blažević-3
In reply to this post by Herbert Valerio Riedel
     A conditional +1 from me, the condition being to allow the same
monad instance code to compile at least with GHC versions 7.8, 7.10, and
8.0 without any CPP directives. I think that can be accomplished by an
extra clarification that the meaning of "override" in

> **Phase 1** *(GHC 8.0)*: Implement new warning in GHC which gets
>     triggered when `Monad` instances explicitly override the
>     default `return` method implementation.

does *not* include a re-definition of

    return = pure

     Yes, I realize this corner case would be a wart in the next
language standard. We could fix that by disabling even this
re-definition in case {#- LANGUAGE Haskell2020 #-} or equivalent is
declared. Perhaps there should be two pragmas, {#- LANGUAGE Haskell2020+
#-} and {#- LANGUAGE Haskell2010-2020 #-}?

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Edward Kmett-2
In reply to this post by Dan Burton
Sadly liftM vs. liftA actually retains a useful distinction, one is a definition of fmap in terms of (>>=) and the other in terms of (<*>). 

`ap` gives a default definition of (<*>) in terms of (>>=), but if someone instead writes (<*>) = liftM2 id today, then erasing the distinction would turn that into a circular definition, transforming obviously-correct existant code silently into a _|_.

-Edward

On Thu, Sep 24, 2015 at 8:36 PM, Dan Burton <[hidden email]> wrote:
What about the derived functions in Control.Monad, such as liftM? Shall we similarly relax their constraints to Applicative and consider them "legacy"? (Did this already happen when I wasn't looking?)


On Thursday, September 24, 2015, John Wiegley <[hidden email]> wrote:
>>>>> Herbert Valerio Riedel <[hidden email]> writes:

> TLDR: To complete the AMP, turn `Monad(return)` method into a
>       top-level binding aliasing `Applicative(pure)`.

Very much +1.

John
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


--
-- Dan Burton

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Edward Kmett-2
In reply to this post by Herbert Valerio Riedel
I'm a rather enthusiastic +1 on this, given a sufficiently long time table for the switch!

We ARE asking a lot of people to break code here.

It does drastically reduce the amount of "magic" involved in the ApplicativeDo story and avoids enshrining the current historical artifact in a future Haskell report that includes the AMP.

I'd also like to consider employing the exact same migration plan for (>>) at the same time. It is redundant with (*>), and the choice of which gets implemented in terms of the other introduces precisely the same set of issues. If we can do that then this would fix the remaining performance issues for mapM, letting us eventually remove that from Traversable as well, moving it to a top level alias in the same way -- maybe not until 8.8 or something, but it'd at least give us a roadmap to get there eventually.

-Edward

On Thu, Sep 24, 2015 at 5:43 PM, Herbert Valerio Riedel <[hidden email]> wrote:
Hello *,

Concluding AMP and MFP, We (David and I) proudly present you the final
installment of the Monad trilogy:


Monad of no `return` Proposal
=============================

TLDR: To complete the AMP, turn `Monad(return)` method into a
      top-level binding aliasing `Applicative(pure)`.


Current Situation
-----------------

With the implementation of Functor-Applicative-Monad Proposal (AMP)[1] and
(at some point) the MonadFail proposal (MFP)[2] the AMP class hierarchy
becomes


    class  Functor f  where
        fmap    :: (a -> b) -> f a -> f b


    class  Functor f => Applicative f  where
        pure    :: a -> f a
        (<*>)   :: f (a -> b) -> f a -> f b

        (*>)    :: f a -> f b -> f b
        u *> v  = …

        (<*)    :: f a -> f b -> f a
        u <* v  = …


    class  Applicative m => Monad m  where
        (>>=)   :: m a -> (a -> m b) -> m b

        return  :: a -> m a
        return  = pure

        (>>)    :: m a -> m b -> m b
        m >> k  = …


    class  Monad m => MonadFail m  where
        fail    :: String -> m a


Consequently, the `Monad` class is left with a now redundant `return`
method as a historic artifact, as there's no compelling reason to
have `pure` and `return` implemented differently.

Traditionally, `return` is often used where `pure` would suffice
today, forcing a `Monad` constraint even if a weaker `Applicative`
would have sufficed.

As a result, language extensions like `ApplicativeDo`[3] have to
rewrite `return` to weaken its `Monad m =>` constraint to
`Applicative m =>` in order to benefit existing code at the cost
of introducing magic behavior at the type level.

Finally, this redundancy becomes even more significant when viewed in
light of the renewed Haskell standardisation process[7]: The next
Haskell Report will almost certainly incorporate the AMP (and MFP)
changes, and there's no justification for the Report to retain
`return` as a method of `Monad`. A good reason would have been to
retain backward compatibility with Haskell 2010. However, as the AMP
superclass hierarchy requires `Monad` instances to be accompanied by
`Applicative` instances (which aren't part of Haskell 2010, c.f. [6]),
backward compatibility with Haskell 2010 goes out the window when it
comes to defining `Monad` instances (unless via use of `-XCPP` or
similar).  Consequently, meeting the high bar for a formal document
such as the Haskell Report demands that `Monad` shall not carry a
redundant `return` method that serves no purpose anymore. Moreover,
getting `return` out of the way is desirable to facilitate
standardising potential candidates such as the earlier mentioned
`ApplicativeDo` in the future and avoids the technical debt incurred
by keeping around this language wart.


Proposed Change
---------------

Remove `return` as a method from the `Monad` class and in its place
define a top-level binding with the weaker `Applicative` typeclass
constraint:


    -- | Legacy alias for 'pure'
    return :: Applicative f => a -> f a
    return = pure


This allows existing code using `return` to benefit from a weaker
typeclass constraint as well as cleaning the `Monad` class from a
redundant method in the post-AMP world.

A possible migration strategy is described further below.


Compatibility Considerations
----------------------------

Generalizing the type signature of a function from a `Monad`
constraint to its superclass `Applicative` doesn't cause new
type-errors in existing code.

However, moving a method to a top-level binding obviously breaks code
that assumes `return` to be a class method. Foremost, code that
defines `Monad` instances it at risk:

### Instance Definitions

Code defining `return` as part of an instance definition
breaks. However, we had the foresight to provide a default
implementation in `base-4.8` for `return` so that the following
represents a proper minimal instance definition post-AMP:


    instance Functor Foo where
        fmap g foo  = …

    instance Applicative Foo where
        pure x      = …
        a1 <*> a2   = …

    instance Monad Foo where
        m >>= f     = …

        -- NB: No mention of `return`


Consequently, it is possible to write forward-compatible instances
that are valid under this proposal starting with GHC 7.10/`base-4.8`.

Heuristically `grep`ing through Hackage source-code reveals a
non-negligible number of packages defining `Monad` instances with
explicit `return` definitions[4]. This has a comparable impact to the
AMP, and similarly will require a transition scheme aided by compiler
warnings.

### Module Import/Export Specifications

A second source of incompatibility may be due to
`import`s. Specifically module import that assert `return` to be a
method of `Monad`, e.g.:

    import Control.Monad  (Monad ((>>=), return))

or

    import Prelude hiding (Monad(..))
    import Control.Monad  (Monad(..)) as Monad

    f = Monad.return ()

The dual situation can occur when re-exporting `return` via module
export specifications.

However, given that `return` is exported by `Prelude` and the examples
above are rather artificial, we don't expect this to be a major source
of breakage in the case of `return`. In fact, a heuristic grep[5] over
Hackage source-code revealed only 21 packages affected.

### Example for writing compatible code


    instance Functor Foo where
        fmap g foo  = …

    instance Applicative Foo where
        pure x      = …
        a1 <*> a2   = …

    instance Monad Foo where
        m >>= f     = …

    #if !(MIN_VERSION_base(4,8,0))
        return = pure
    #endif


Migration Strategy
------------------

The migration strategy is straightforward:

**Phase 1** *(GHC 8.0)*: Implement new warning in GHC which gets
   triggered when `Monad` instances explicitly override the
   default `return` method implementation.

**Phase 2** *(GHC 8.2 or later)*: When we're confident that the
   majority of Hackage has reacted to the warning (with the help of
   Stackage actively pursuing maintainers to update their packages) we
   turn the `return` method into a top-level binding and remove the
   warning implemented in Phase 1 from GHC again.


Discussion period
-----------------

A discussion period of three weeks (until 2015-10-15) should be enough
to allow everyone to chime in as well as leave enough time to make the
required preparations for GHC 8.0 should this proposal pass as we hope.

----

 [1]: https://wiki.haskell.org/Functor-Applicative-Monad_Proposal
 [2]: https://wiki.haskell.org/MonadFail_Proposal
 [3]: https://ghc.haskell.org/trac/ghc/wiki/ApplicativeDo
 [4]: https://gist.github.com/hvr/b0e34463d85b58f169d9
 [5]: https://gist.github.com/hvr/afcd040783d980594883
 [6]: https://ghc.haskell.org/trac/ghc/ticket/9590
 [7]: https://mail.haskell.org/pipermail/haskell-prime/2015-September/003936.html

--

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

David Feuer

Yes, and I think there are still some more overly-specific things that come in here too, such as replicateM and filterM, which I don't think have been generalized yet.

On Sep 24, 2015 10:40 PM, "Edward Kmett" <[hidden email]> wrote:
I'm a rather enthusiastic +1 on this, given a sufficiently long time table for the switch!

We ARE asking a lot of people to break code here.

It does drastically reduce the amount of "magic" involved in the ApplicativeDo story and avoids enshrining the current historical artifact in a future Haskell report that includes the AMP.

I'd also like to consider employing the exact same migration plan for (>>) at the same time. It is redundant with (*>), and the choice of which gets implemented in terms of the other introduces precisely the same set of issues. If we can do that then this would fix the remaining performance issues for mapM, letting us eventually remove that from Traversable as well, moving it to a top level alias in the same way -- maybe not until 8.8 or something, but it'd at least give us a roadmap to get there eventually.

-Edward

On Thu, Sep 24, 2015 at 5:43 PM, Herbert Valerio Riedel <[hidden email]> wrote:
Hello *,

Concluding AMP and MFP, We (David and I) proudly present you the final
installment of the Monad trilogy:


Monad of no `return` Proposal
=============================

TLDR: To complete the AMP, turn `Monad(return)` method into a
      top-level binding aliasing `Applicative(pure)`.


Current Situation
-----------------

With the implementation of Functor-Applicative-Monad Proposal (AMP)[1] and
(at some point) the MonadFail proposal (MFP)[2] the AMP class hierarchy
becomes


    class  Functor f  where
        fmap    :: (a -> b) -> f a -> f b


    class  Functor f => Applicative f  where
        pure    :: a -> f a
        (<*>)   :: f (a -> b) -> f a -> f b

        (*>)    :: f a -> f b -> f b
        u *> v  = …

        (<*)    :: f a -> f b -> f a
        u <* v  = …


    class  Applicative m => Monad m  where
        (>>=)   :: m a -> (a -> m b) -> m b

        return  :: a -> m a
        return  = pure

        (>>)    :: m a -> m b -> m b
        m >> k  = …


    class  Monad m => MonadFail m  where
        fail    :: String -> m a


Consequently, the `Monad` class is left with a now redundant `return`
method as a historic artifact, as there's no compelling reason to
have `pure` and `return` implemented differently.

Traditionally, `return` is often used where `pure` would suffice
today, forcing a `Monad` constraint even if a weaker `Applicative`
would have sufficed.

As a result, language extensions like `ApplicativeDo`[3] have to
rewrite `return` to weaken its `Monad m =>` constraint to
`Applicative m =>` in order to benefit existing code at the cost
of introducing magic behavior at the type level.

Finally, this redundancy becomes even more significant when viewed in
light of the renewed Haskell standardisation process[7]: The next
Haskell Report will almost certainly incorporate the AMP (and MFP)
changes, and there's no justification for the Report to retain
`return` as a method of `Monad`. A good reason would have been to
retain backward compatibility with Haskell 2010. However, as the AMP
superclass hierarchy requires `Monad` instances to be accompanied by
`Applicative` instances (which aren't part of Haskell 2010, c.f. [6]),
backward compatibility with Haskell 2010 goes out the window when it
comes to defining `Monad` instances (unless via use of `-XCPP` or
similar).  Consequently, meeting the high bar for a formal document
such as the Haskell Report demands that `Monad` shall not carry a
redundant `return` method that serves no purpose anymore. Moreover,
getting `return` out of the way is desirable to facilitate
standardising potential candidates such as the earlier mentioned
`ApplicativeDo` in the future and avoids the technical debt incurred
by keeping around this language wart.


Proposed Change
---------------

Remove `return` as a method from the `Monad` class and in its place
define a top-level binding with the weaker `Applicative` typeclass
constraint:


    -- | Legacy alias for 'pure'
    return :: Applicative f => a -> f a
    return = pure


This allows existing code using `return` to benefit from a weaker
typeclass constraint as well as cleaning the `Monad` class from a
redundant method in the post-AMP world.

A possible migration strategy is described further below.


Compatibility Considerations
----------------------------

Generalizing the type signature of a function from a `Monad`
constraint to its superclass `Applicative` doesn't cause new
type-errors in existing code.

However, moving a method to a top-level binding obviously breaks code
that assumes `return` to be a class method. Foremost, code that
defines `Monad` instances it at risk:

### Instance Definitions

Code defining `return` as part of an instance definition
breaks. However, we had the foresight to provide a default
implementation in `base-4.8` for `return` so that the following
represents a proper minimal instance definition post-AMP:


    instance Functor Foo where
        fmap g foo  = …

    instance Applicative Foo where
        pure x      = …
        a1 <*> a2   = …

    instance Monad Foo where
        m >>= f     = …

        -- NB: No mention of `return`


Consequently, it is possible to write forward-compatible instances
that are valid under this proposal starting with GHC 7.10/`base-4.8`.

Heuristically `grep`ing through Hackage source-code reveals a
non-negligible number of packages defining `Monad` instances with
explicit `return` definitions[4]. This has a comparable impact to the
AMP, and similarly will require a transition scheme aided by compiler
warnings.

### Module Import/Export Specifications

A second source of incompatibility may be due to
`import`s. Specifically module import that assert `return` to be a
method of `Monad`, e.g.:

    import Control.Monad  (Monad ((>>=), return))

or

    import Prelude hiding (Monad(..))
    import Control.Monad  (Monad(..)) as Monad

    f = Monad.return ()

The dual situation can occur when re-exporting `return` via module
export specifications.

However, given that `return` is exported by `Prelude` and the examples
above are rather artificial, we don't expect this to be a major source
of breakage in the case of `return`. In fact, a heuristic grep[5] over
Hackage source-code revealed only 21 packages affected.

### Example for writing compatible code


    instance Functor Foo where
        fmap g foo  = …

    instance Applicative Foo where
        pure x      = …
        a1 <*> a2   = …

    instance Monad Foo where
        m >>= f     = …

    #if !(MIN_VERSION_base(4,8,0))
        return = pure
    #endif


Migration Strategy
------------------

The migration strategy is straightforward:

**Phase 1** *(GHC 8.0)*: Implement new warning in GHC which gets
   triggered when `Monad` instances explicitly override the
   default `return` method implementation.

**Phase 2** *(GHC 8.2 or later)*: When we're confident that the
   majority of Hackage has reacted to the warning (with the help of
   Stackage actively pursuing maintainers to update their packages) we
   turn the `return` method into a top-level binding and remove the
   warning implemented in Phase 1 from GHC again.


Discussion period
-----------------

A discussion period of three weeks (until 2015-10-15) should be enough
to allow everyone to chime in as well as leave enough time to make the
required preparations for GHC 8.0 should this proposal pass as we hope.

----

 [1]: https://wiki.haskell.org/Functor-Applicative-Monad_Proposal
 [2]: https://wiki.haskell.org/MonadFail_Proposal
 [3]: https://ghc.haskell.org/trac/ghc/wiki/ApplicativeDo
 [4]: https://gist.github.com/hvr/b0e34463d85b58f169d9
 [5]: https://gist.github.com/hvr/afcd040783d980594883
 [6]: https://ghc.haskell.org/trac/ghc/ticket/9590
 [7]: https://mail.haskell.org/pipermail/haskell-prime/2015-September/003936.html

--

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

M Farkas-Dyck
On 24/09/2015, David Feuer <[hidden email]> wrote:
> Yes, and I think there are still some more overly-specific things that come
> in here too, such as replicateM and filterM, which I don't think have been
> generalized yet.

Someone posted a patch for that...

https://ghc.haskell.org/trac/ghc/ticket/10168
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Andreas Abel
In reply to this post by Edward Kmett-2
On 25.09.2015 04:40, Edward Kmett wrote:
> I'd also like to consider employing the exact same migration plan for
> (>>) at the same time. It is redundant with (*>), and the choice of
> which gets implemented in terms of the other introduces precisely the
> same set of issues. If we can do that then this would fix the remaining
> performance issues for mapM, letting us eventually remove that from
> Traversable as well, moving it to a top level alias in the same way --
> maybe not until 8.8 or something, but it'd at least give us a roadmap to
> get there eventually.

+1 on bundling these changes.

> On Thu, Sep 24, 2015 at 5:43 PM, Herbert Valerio Riedel <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Hello *,
>
>     Concluding AMP and MFP, We (David and I) proudly present you the final
>     installment of the Monad trilogy:
>
>
>     Monad of no `return` Proposal
>     =============================
>
>     TLDR: To complete the AMP, turn `Monad(return)` method into a
>            top-level binding aliasing `Applicative(pure)`.
>
>
>     Current Situation
>     -----------------
>
>     With the implementation of Functor-Applicative-Monad Proposal
>     (AMP)[1] and
>     (at some point) the MonadFail proposal (MFP)[2] the AMP class hierarchy
>     becomes
>
>
>          class  Functor f  where
>              fmap    :: (a -> b) -> f a -> f b
>
>
>          class  Functor f => Applicative f  where
>              pure    :: a -> f a
>              (<*>)   :: f (a -> b) -> f a -> f b
>
>              (*>)    :: f a -> f b -> f b
>              u *> v  = …
>
>              (<*)    :: f a -> f b -> f a
>              u <* v  = …
>
>
>          class  Applicative m => Monad m  where
>              (>>=)   :: m a -> (a -> m b) -> m b
>
>              return  :: a -> m a
>              return  = pure
>
>              (>>)    :: m a -> m b -> m b
>              m >> k  = …
>
>
>          class  Monad m => MonadFail m  where
>              fail    :: String -> m a
>
>
>     Consequently, the `Monad` class is left with a now redundant `return`
>     method as a historic artifact, as there's no compelling reason to
>     have `pure` and `return` implemented differently.
>
>     Traditionally, `return` is often used where `pure` would suffice
>     today, forcing a `Monad` constraint even if a weaker `Applicative`
>     would have sufficed.
>
>     As a result, language extensions like `ApplicativeDo`[3] have to
>     rewrite `return` to weaken its `Monad m =>` constraint to
>     `Applicative m =>` in order to benefit existing code at the cost
>     of introducing magic behavior at the type level.
>
>     Finally, this redundancy becomes even more significant when viewed in
>     light of the renewed Haskell standardisation process[7]: The next
>     Haskell Report will almost certainly incorporate the AMP (and MFP)
>     changes, and there's no justification for the Report to retain
>     `return` as a method of `Monad`. A good reason would have been to
>     retain backward compatibility with Haskell 2010. However, as the AMP
>     superclass hierarchy requires `Monad` instances to be accompanied by
>     `Applicative` instances (which aren't part of Haskell 2010, c.f. [6]),
>     backward compatibility with Haskell 2010 goes out the window when it
>     comes to defining `Monad` instances (unless via use of `-XCPP` or
>     similar).  Consequently, meeting the high bar for a formal document
>     such as the Haskell Report demands that `Monad` shall not carry a
>     redundant `return` method that serves no purpose anymore. Moreover,
>     getting `return` out of the way is desirable to facilitate
>     standardising potential candidates such as the earlier mentioned
>     `ApplicativeDo` in the future and avoids the technical debt incurred
>     by keeping around this language wart.
>
>
>     Proposed Change
>     ---------------
>
>     Remove `return` as a method from the `Monad` class and in its place
>     define a top-level binding with the weaker `Applicative` typeclass
>     constraint:
>
>
>          -- | Legacy alias for 'pure'
>          return :: Applicative f => a -> f a
>          return = pure
>
>
>     This allows existing code using `return` to benefit from a weaker
>     typeclass constraint as well as cleaning the `Monad` class from a
>     redundant method in the post-AMP world.
>
>     A possible migration strategy is described further below.
>
>
>     Compatibility Considerations
>     ----------------------------
>
>     Generalizing the type signature of a function from a `Monad`
>     constraint to its superclass `Applicative` doesn't cause new
>     type-errors in existing code.
>
>     However, moving a method to a top-level binding obviously breaks code
>     that assumes `return` to be a class method. Foremost, code that
>     defines `Monad` instances it at risk:
>
>     ### Instance Definitions
>
>     Code defining `return` as part of an instance definition
>     breaks. However, we had the foresight to provide a default
>     implementation in `base-4.8` for `return` so that the following
>     represents a proper minimal instance definition post-AMP:
>
>
>          instance Functor Foo where
>              fmap g foo  = …
>
>          instance Applicative Foo where
>              pure x      = …
>              a1 <*> a2   = …
>
>          instance Monad Foo where
>              m >>= f     = …
>
>              -- NB: No mention of `return`
>
>
>     Consequently, it is possible to write forward-compatible instances
>     that are valid under this proposal starting with GHC 7.10/`base-4.8`.
>
>     Heuristically `grep`ing through Hackage source-code reveals a
>     non-negligible number of packages defining `Monad` instances with
>     explicit `return` definitions[4]. This has a comparable impact to the
>     AMP, and similarly will require a transition scheme aided by compiler
>     warnings.
>
>     ### Module Import/Export Specifications
>
>     A second source of incompatibility may be due to
>     `import`s. Specifically module import that assert `return` to be a
>     method of `Monad`, e.g.:
>
>          import Control.Monad  (Monad ((>>=), return))
>
>     or
>
>          import Prelude hiding (Monad(..))
>          import Control.Monad  (Monad(..)) as Monad
>
>          f = Monad.return ()
>
>     The dual situation can occur when re-exporting `return` via module
>     export specifications.
>
>     However, given that `return` is exported by `Prelude` and the examples
>     above are rather artificial, we don't expect this to be a major source
>     of breakage in the case of `return`. In fact, a heuristic grep[5] over
>     Hackage source-code revealed only 21 packages affected.
>
>     ### Example for writing compatible code
>
>
>          instance Functor Foo where
>              fmap g foo  = …
>
>          instance Applicative Foo where
>              pure x      = …
>              a1 <*> a2   = …
>
>          instance Monad Foo where
>              m >>= f     = …
>
>          #if !(MIN_VERSION_base(4,8,0))
>              return = pure
>          #endif
>
>
>     Migration Strategy
>     ------------------
>
>     The migration strategy is straightforward:
>
>     **Phase 1** *(GHC 8.0)*: Implement new warning in GHC which gets
>         triggered when `Monad` instances explicitly override the
>         default `return` method implementation.
>
>     **Phase 2** *(GHC 8.2 or later)*: When we're confident that the
>         majority of Hackage has reacted to the warning (with the help of
>         Stackage actively pursuing maintainers to update their packages) we
>         turn the `return` method into a top-level binding and remove the
>         warning implemented in Phase 1 from GHC again.
>
>
>     Discussion period
>     -----------------
>
>     A discussion period of three weeks (until 2015-10-15) should be enough
>     to allow everyone to chime in as well as leave enough time to make the
>     required preparations for GHC 8.0 should this proposal pass as we hope.
>
>     ----
>
>       [1]: https://wiki.haskell.org/Functor-Applicative-Monad_Proposal
>       [2]: https://wiki.haskell.org/MonadFail_Proposal
>       [3]: https://ghc.haskell.org/trac/ghc/wiki/ApplicativeDo
>       [4]: https://gist.github.com/hvr/b0e34463d85b58f169d9
>       [5]: https://gist.github.com/hvr/afcd040783d980594883
>       [6]: https://ghc.haskell.org/trac/ghc/ticket/9590
>       [7]:
>     https://mail.haskell.org/pipermail/haskell-prime/2015-September/003936.html
>
>     --
>
>     _______________________________________________
>     Libraries mailing list
>     [hidden email] <mailto:[hidden email]>
>     http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>
>
>
>
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>


--
Andreas Abel  <><      Du bist der geliebte Mensch.

Department of Computer Science and Engineering
Chalmers and Gothenburg University, Sweden

[hidden email]
http://www2.tcs.ifi.lmu.de/~abel/
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Bardur Arantsson-2
In reply to this post by Herbert Valerio Riedel
On 09/24/2015 11:43 PM, Herbert Valerio Riedel wrote:
> Hello *,
>

+1, just a minor... nitpick, I guess:

>
>     -- | Legacy alias for 'pure'
>     return :: Applicative f => a -> f a
>     return = pure
>

I propse to remove the "Legacy" designation (see below for reasoning).
There should probably also be some reference to the Applicative type
class, so I'd propose a wording more like:

    Alias for 'pure' in the 'Applicative' type class.

Reasoning: I happen to rather like "return" for purely pedagogical
purposes since it lets you pretend (as a sufficient-for-beginners
approximation) that code in the do-notation in IO is imperative code and
"return" is the usual name for what it does in that context. I think
that has a certain value, but "Legacy" is quite off-putting.

Presumably we aren't talking about removing "return" itself any time in
the next, say, 5-10 years...? (That _would_ break a hell of a lot of code.)

Anyway, just a (very) minor nitpick to consider.

> However, given that `return` is exported by `Prelude` and the examples
> above are rather artificial, we don't expect this to be a major source
> of breakage in the case of `return`. In fact, a heuristic grep[5] over
> Hackage source-code revealed only 21 packages affected.

How many reverse dependencies do those packages have? (I.e. how many
packages are going to require at least a version bump.)

Regards,

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Henrik Nilsson-2
In reply to this post by Herbert Valerio Riedel
Hi,

At least with the current situation, it is possible (from my experience
so far, but I don't claim to have tested extensively) to write code
that works both with the old class hierarchy as well as the new:

   * Add an import Control.Applicative
   * Add an explicit method definition "return = pure" for Monad
     instances
   * Add Applicative to contexts in a few strategic places.

That's a big plus in my books for people who for one reason or another
would like to write code that works against an as broad range of
different versions of the available Haskell tools as possible.

On the other hand, I don't really understand the rationale:

 > Traditionally, `return` is often used where `pure` would suffice
 > today, forcing a `Monad` constraint even if a weaker `Applicative`
 > would have sufficed.
 >
 > As a result, language extensions like `ApplicativeDo`[3] have to
 > rewrite `return` to weaken its `Monad m =>` constraint to
 > `Applicative m =>` in order to benefit existing code at the cost
 > of introducing magic behavior at the type level.

If code is genuinely applicative, why not encourage this to be
clearly signalled by use of "pure" instead of "return"?
Surely that would benefit long-term readability a lot more
than supporting use of the "wrong" function.

And as ApplicativeDo is a new extension, removing the magic
so as to force such a change for code that really is applicative
ought not to cause that much trouble for existing code.

Thus, encourage (or force) people to say what they mean by
using "pure" and "return" appropriately.

I'm thus (very) unconvinced about the merits of this proposal.

Best,

/Henrik

--
Henrik Nilsson
School of Computer Science
The University of Nottingham
[hidden email]




This message and any attachment are intended solely for the addressee
and may contain confidential information. If you have received this
message in error, please send it back to me, and immediately delete it.

Please do not use, copy or disclose the information contained in this
message or in any attachment.  Any views or opinions expressed by the
author of this email do not necessarily reflect the views of the
University of Nottingham.

This message has been checked for viruses but the contents of an
attachment may still contain software viruses which could damage your
computer system, you are advised to perform your own checks. Email
communications with the University of Nottingham may be monitored as
permitted by UK legislation.

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Vincent Hanquez
In reply to this post by Herbert Valerio Riedel


On 24/09/2015 22:43, Herbert Valerio Riedel wrote:
> Hello *,
>
> Concluding AMP and MFP, We (David and I) proudly present you the final
> installment of the Monad trilogy:
>
Very much +1, despite all the compat annoyances this is going to bring.

--
Vincent
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Roman Cheplyaka-2
On 09/25/2015 01:14 PM, Vincent Hanquez wrote:
>
>
> On 24/09/2015 22:43, Herbert Valerio Riedel wrote:
>> Hello *,
>>
>> Concluding AMP and MFP, We (David and I) proudly present you the final
>> installment of the Monad trilogy:
>>
> Very much +1, despite all the compat annoyances this is going to bring.

Ditto.



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Bertram Felgenhauer-2
In reply to this post by David Feuer
David Feuer wrote:
> +1 on both the goal and the means of reaching it. That said, I suspect
> the claim that "This has a comparable impact to the AMP" may be overly
> optimistic.

I want to echo this concern. In fact, the most common way of fixing code
after the AMP proposal seems to have been to mechanically add instances

  instance Functor Foo where
    fmap = liftM

  instance Applicative Foo where
    pure = return
    (<*>) = ap

whenever the compiler complained about a missing Applicative instance for
a monad Foo. All those Applicative instances would have to be rewritten
under the MRP proposal, and that task is not purely mechanical, since it
involves moving existing code, so I'd say that the burden would be higher
than after the AMP proposal.

How many of those Applicative instances are there in hackage?

Cheers,

Bertram
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Alexander Berntsen
In reply to this post by Herbert Valerio Riedel
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Enthusiastic +1 from me too, of course.

- --
Alexander
[hidden email]
https://secure.plaimi.net/~alexander
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBCgAGBQJWBTfiAAoJENQqWdRUGk8BU00QAMQfZo07CKomsjqcwNCDNqdm
ifIhiz2kldR+A/gp6t/8IRf0RG3ZgZfwxhR5s/BWt7yV28napZfTMHPTfV8gE+bm
V8AzvsXe/XLa9gTDyxqnY+ovYBDnEqmbX3SU03rRdtcN3jHiNuFkfIEIkRx6+HVx
BKfoebxD7r1tgs/4nxjD8HljJEh6W8ux2Q8+sMWiCJEbVN5ixzTzGSk28vT2Ldyl
GkoZJoXYM4K3WVCn23UmH9eokbdbnaCu2WRqzGgM7eQf+qqpouSjE3KRL5d9O/pE
NMJIrNkC1L613GpfNeHLikOCKd78vbT0xnXyKHwAxv4Cr/7IZI3dyu+5MYwFntrY
cdX7PgNQw7RN/tvZ63OOaRQEqvQfiOSdhPdFxAF5MabPNYMZMjIHqJuQseBaiUJf
SWOU9oYNWW7XQVaQRVS5bP0KvRUhsA2+QXEd6pnhBEZ6u7qRQhaJowjca/A1TbB/
LHVG9nXE04fvc+CRkMK/xZEbuNWiMF0p4CZUiyeuAzhcZ9dge367ExfrTpTSLz8O
Gfh04LgWs3rnvc3w8yhJJjcfsHhYZKQJMv40Rn8dgE/hyGFRpwQvBvFolZtFBZiS
h6A/MyLDaSJCw3jwj+cU5PGLULGzdfNnTRlJ/jb4/CD2xUEOaQcAd+NvIJOlREcK
RZBk4o5MU1aCsujOzjRd
=VfnC
-----END PGP SIGNATURE-----
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Greg Weber
Is the upgrade automatable with tooling that analyzes Haskell source code?
If so can we provide an executable that will automatically upgrade packages?
Pull requests could even be sent automatically.

On Fri, Sep 25, 2015 at 5:02 AM, Alexander Berntsen <[hidden email]> wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Enthusiastic +1 from me too, of course.

- --
Alexander
[hidden email]
https://secure.plaimi.net/~alexander
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBCgAGBQJWBTfiAAoJENQqWdRUGk8BU00QAMQfZo07CKomsjqcwNCDNqdm
ifIhiz2kldR+A/gp6t/8IRf0RG3ZgZfwxhR5s/BWt7yV28napZfTMHPTfV8gE+bm
V8AzvsXe/XLa9gTDyxqnY+ovYBDnEqmbX3SU03rRdtcN3jHiNuFkfIEIkRx6+HVx
BKfoebxD7r1tgs/4nxjD8HljJEh6W8ux2Q8+sMWiCJEbVN5ixzTzGSk28vT2Ldyl
GkoZJoXYM4K3WVCn23UmH9eokbdbnaCu2WRqzGgM7eQf+qqpouSjE3KRL5d9O/pE
NMJIrNkC1L613GpfNeHLikOCKd78vbT0xnXyKHwAxv4Cr/7IZI3dyu+5MYwFntrY
cdX7PgNQw7RN/tvZ63OOaRQEqvQfiOSdhPdFxAF5MabPNYMZMjIHqJuQseBaiUJf
SWOU9oYNWW7XQVaQRVS5bP0KvRUhsA2+QXEd6pnhBEZ6u7qRQhaJowjca/A1TbB/
LHVG9nXE04fvc+CRkMK/xZEbuNWiMF0p4CZUiyeuAzhcZ9dge367ExfrTpTSLz8O
Gfh04LgWs3rnvc3w8yhJJjcfsHhYZKQJMv40Rn8dgE/hyGFRpwQvBvFolZtFBZiS
h6A/MyLDaSJCw3jwj+cU5PGLULGzdfNnTRlJ/jb4/CD2xUEOaQcAd+NvIJOlREcK
RZBk4o5MU1aCsujOzjRd
=VfnC
-----END PGP SIGNATURE-----
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

David Feuer

It *should* be possible to recognize

return = pure
return x = pure x
pure = return
pure x = return x
and also cases where pure and return are defined the same up to alpha equivalence. It should also be possible to fix this up automatically, but there are several different fixes that programmers may want. Many package maintainers strive to support old GHC versions--some as far back as 7.0--and a few even try to keep their code running in Hugs, although that seems a bit silly. Those maintainers will probably want to use MIN_VERSION_base to maintain backwards compatibility. Some of those packages (e.g., containers) approximate fake versions of that macro for non-cabal compilation, but such conditional definitions may occur in each file separately or in a global include file.

On Sep 25, 2015 11:35 AM, "Greg Weber" <[hidden email]> wrote:
Is the upgrade automatable with tooling that analyzes Haskell source code?
If so can we provide an executable that will automatically upgrade packages?
Pull requests could even be sent automatically.

On Fri, Sep 25, 2015 at 5:02 AM, Alexander Berntsen <[hidden email]> wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Enthusiastic +1 from me too, of course.

- --
Alexander
[hidden email]
https://secure.plaimi.net/~alexander
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBCgAGBQJWBTfiAAoJENQqWdRUGk8BU00QAMQfZo07CKomsjqcwNCDNqdm
ifIhiz2kldR+A/gp6t/8IRf0RG3ZgZfwxhR5s/BWt7yV28napZfTMHPTfV8gE+bm
V8AzvsXe/XLa9gTDyxqnY+ovYBDnEqmbX3SU03rRdtcN3jHiNuFkfIEIkRx6+HVx
BKfoebxD7r1tgs/4nxjD8HljJEh6W8ux2Q8+sMWiCJEbVN5ixzTzGSk28vT2Ldyl
GkoZJoXYM4K3WVCn23UmH9eokbdbnaCu2WRqzGgM7eQf+qqpouSjE3KRL5d9O/pE
NMJIrNkC1L613GpfNeHLikOCKd78vbT0xnXyKHwAxv4Cr/7IZI3dyu+5MYwFntrY
cdX7PgNQw7RN/tvZ63OOaRQEqvQfiOSdhPdFxAF5MabPNYMZMjIHqJuQseBaiUJf
SWOU9oYNWW7XQVaQRVS5bP0KvRUhsA2+QXEd6pnhBEZ6u7qRQhaJowjca/A1TbB/
LHVG9nXE04fvc+CRkMK/xZEbuNWiMF0p4CZUiyeuAzhcZ9dge367ExfrTpTSLz8O
Gfh04LgWs3rnvc3w8yhJJjcfsHhYZKQJMv40Rn8dgE/hyGFRpwQvBvFolZtFBZiS
h6A/MyLDaSJCw3jwj+cU5PGLULGzdfNnTRlJ/jb4/CD2xUEOaQcAd+NvIJOlREcK
RZBk4o5MU1aCsujOzjRd
=VfnC
-----END PGP SIGNATURE-----
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
1234 ... 13