basvandijk/monad-control

CounterT example requires UndecidableInstances

Closed this issue · 2 comments

Running on GHC 8.0.1. Compiling the CounterT example verbatim gives:

src/Example.hs:90:10: error:
    • The type family application ‘StT (StateT Int) a’
        is no smaller than the instance head
      (Use UndecidableInstances to permit this)
    • In the type instance declaration for ‘StT’
      In the instance declaration for ‘MonadTransControl CounterT’

This was a bit surprising since the documentation doesn't mention UndecidableInstances, only GeneralizedNewtypeDeriving. Am I doing something wrong, or is the documentation wrong?

I think you're right. It requires UndecidableInstances and TypeFamilies.

The example for the MonadBaseControl instance also requires a couple language pragmas. It would be nice to get these added to the documentation.

Here is an example program that you can be used to reproduce this issue. If you have stack installed, all you need to do is save it as a file and execute it. If any of the language pragmas are removed, a compile error will occur.

#!/usr/bin/env stack
-- stack --verbose --resolver lts-8.4 --install-ghc --no-system-ghc runghc --package transformers --package mtl --package monad-control -- -Wall -fwarn-incomplete-uni-patterns -fwarn-incomplete-record-updates -fwarn-monomorphism-restriction

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

module Main where

import Control.Monad.Trans.Class (MonadTrans)
import Control.Monad.Trans.Control
       (MonadTransControl(StT, liftWith, restoreT), defaultLiftWith,
        defaultRestoreT)
import Control.Monad.State (StateT)

main :: IO ()
main = return ()

newtype CounterT m a = CounterT {unCounterT :: StateT Int m a}
  deriving (Functor, Applicative, Monad, MonadTrans)

instance MonadTransControl CounterT where
  type StT CounterT a = StT (StateT Int) a
  liftWith = defaultLiftWith CounterT unCounterT
  restoreT = defaultRestoreT CounterT