Reputation: 3240
I have a function
logger :: ToJSON a => String -> a -> IO ()
I'd like to make an alias for this type signature
type Logger = ToJSON a => String -> a -> IO ()
such that I can make more functions with the same type signature:
logger :: Logger
simpleLogger :: Logger
But I'm getting an error:
• Illegal qualified type: ToJSON a => String -> a -> IO ()
Perhaps you intended to use RankNTypes or Rank2Types
• In the type synonym declaration for ‘Logger’
Upvotes: 4
Views: 188
Reputation: 48631
GHC requires the RankNTypes
extension to allow types with constraints to appear
In the definition of a type synonym:
type A x = C x => x -> Y
In a field of a newtype or datatype declaration, or
newtype B x = B (C x => x -> Y)
data D x = D (C x => x -> Y)
On the left-hand side of an arrow.
f :: (C x => x -> Y) -> Z
This may seem a bit surprising (it did to me), since these types are all actually rank-1. However, I have been told that the inference requirements of these types are actually quite similar to those of higher-rank types. In both cases, there's an argument that may need to be inferred. In the case of a higher-rank type, that is a type argument. In the case of a constrained type, that is a dictionary argument.
If you are writing a Haskell module, add
{-# language RankNTypes #-}
to the very top of the source file (before the module
line). If you are using GHCi, either run
ghci -XRankNTypes
or type
:set -XRankNTypes
at the GHCi prompt.
Upvotes: 3