Leo Zhang
Leo Zhang

Reputation: 3240

how to use typeclass in `type` keyword?

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

Answers (1)

dfeuer
dfeuer

Reputation: 48631

GHC requires the RankNTypes extension to allow types with constraints to appear

  1. In the definition of a type synonym:

    type A x = C x => x -> Y
    
  2. 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)
    
  3. 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

Related Questions