[GHC] #11128: New `-fwarn-noncanonical-monad-instances` warning
GHC
ghc-devs at haskell.org
Tue Nov 24 12:19:52 UTC 2015
#11128: New `-fwarn-noncanonical-monad-instances` warning
-------------------------------------+-------------------------------------
Reporter: hvr | Owner: hvr
Type: feature request | Status: patch
Priority: normal | Milestone: 8.0.1
Component: Compiler | Version: 7.10.2
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s): Phab:D1516
Wiki Page: |
-------------------------------------+-------------------------------------
Description changed by hvr:
Old description:
> When declaring `Applicative` and `Monad` instances, there's a degree of
> freedom in which way to define `return`,`pure`,`(>>)`,`(*>)`. For
> instance, defining
>
> {{{#!hs
> instance Applicative T1 where
> pure = return
> (<*>) = ap
>
> instance Monad T1 where
> return = ...
> (>>=) = ...
> (>>) = ...
> }}}
>
> is ok, but it's leaves `(*>)` with a possibly less optimised version than
> `(>>)`. This can cause performance regressions when generalising code
> from `Monad` to `Applicative`.
>
> Moreover, starting with `base-4.8`, the `return` method gained a default
> implementation `return = pure` which follows the preferred or "canonical"
> direction of having implementations flow from superclasses to their
> subclasses.
>
> So this warning is a "lint"-style check to help detect `Monad` instances
> where the definitions of `return`/`(>>)` are not canonical, i.e. don't
> match `return = pure` and `(>>) = (*>)` respectively.
New description:
When declaring `Applicative` and `Monad` instances, there's a degree of
freedom in which way to define `return`,`pure`,`(>>)`,`(*>)`. For
instance, defining
{{{#!hs
instance Applicative T1 where
pure = return
(<*>) = ap
instance Monad T1 where
return = ...
(>>=) = ...
(>>) = {- optimised impl -}
}}}
is ok, but this leaves `(*>)` with a possibly less optimised version than
`(>>)`. This can cause performance regressions when generalising code from
`Monad` to `Applicative`.
Moreover, starting with `base-4.8`, the `return` method gained a default
implementation `return = pure` which follows the preferred or "canonical"
direction of having implementations flow from superclasses to their
subclasses.
A proper "canonical" definition of `T1` is consequently:
{{{#!hs
instance Applicative T1 where
pure = ...
(<*>) = ap
(*>) = {- optimised impl -}
instance Monad T1 where
return = pure -- can be left off since base-4.8
(>>=) = ...
(>>) = (*>) -- NB: default impl of (>>) /= (*>)
}}}
So this warning is a "lint"-style check to help detect `Monad` instances
where the definitions of `return`/`(>>)` are not canonical, i.e. don't
match `return = pure` and `(>>) = (*>)` respectively.
--
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11128#comment:6>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list