[GHC] #12418: Make `MonadCont (ContT r m)` polykinded (r::k), (m::k -> Type)
GHC
ghc-devs at haskell.org
Sun Jul 24 00:11:41 UTC 2016
#12418: Make `MonadCont (ContT r m)` polykinded (r::k), (m::k -> Type)
-------------------------------------+-------------------------------------
Reporter: Iceland_jack | Owner:
Type: feature request | Status: new
Priority: normal | Milestone:
Component: Core Libraries | Version: 8.0.1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by ekmett):
{{{#!hs
instance MonadState s m => MonadState s (ContT @Type r m)
}}}
suffers the same sort of problem as the MonadCont instance, if you define
it pointwise at @Type. If m and r are left underspecified kind wise and
you go to invoke a `MonadState s ` operation, it has no reason to pick
that instance, unless it can figure out `k = Type`, hence `m :: Type ->
Type`, it won't discharge the head and go looking for `MonadState s m`
from the body and use this instance. It'll just whine about a missing
instance at an unknown kind. So if `m` is polykinded like `Proxy`, which
has kind k -> *, but at * -> * is a perfectly legitimate monad (it is the
unique-up-to-isomorphism terminal monad), then this no longer
monomorphizes m to kind * -> * to go look for this possible instance.
The compiler doesn't know if you doesn't know someone won't make up some
completely different instance like:
{{{#!hs
instance MonadState () (ContT @Whatever r m) where
get = return ()
put () = return ()
}}}
pointwise at another kind. This 'can't do the same sort of lifting as the
typical MonadState, so it really doesn't have any place being defined on
this data type and any such instance will necessarily be an orphan.
As you note Functor, Applicative, Monad all work fine, because really if
you look at ContT the fact that m and r exist as separate entities doesn't
matter to those instances at all, those are just the basic `Cont r'`
instances instantiated at `r' = m r`. They never use 'm' to do any work,
and just teeat `m r` as an opaque blob. Once you start lifting monad
transformer instances for things like MonadState, MonadWriter, etc. over
`ContT r` then we need to know `m :: Type -> Type`, because we finally
start interacting with the extra structure we've given our CPS'd result
type.
You get a slightly more general callCC at the expense of screwing up
inference for every monad transformer instance, that can only be taken
advantage of to make instances that act at different kinds inconsistently
with the instances that are already in place.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12418#comment:5>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list