Search code examples
haskelltypeclassnewtype

Can a typeclass constraint be used in a newtype definition?


Suppose we have the following newtype definition:

newtype A = A { _run :: Monad m => A -> [Int] -> m Int }

This does not compile with GHC 8.0.2:

error: Not in scope: type variable ‘m’

Replacing m with a concrete typeclass like IO or [] does compile, as I would expect. Given that this is ok, why does GHC not allow the signature above? What is wrong with adding a typeclass constraint inside of this newtype?


Solution

  • This is possible:

    {-# LANGUAGE RankNTypes #-}
    newtype A = A { _run :: forall m. Monad m => A -> [Int] -> m Int }
    

    It's hard to tell what you want to do, but this isn't very usable. Any value of type A needs to work for all monads (you don't get to choose).

    This is also possible, with the same restrictions:

    {-# LANGUAGE GADTs #-}
    data A where A :: Monad m => (A -> [Int] -> m Int) -> A
    

    But perhaps you mean something more like

    newtype A m = A { _run :: A m -> [Int] -> m Int }
    

    This allows for values of different types of A using different monads.