Question

Given a GADT indexed by a phantom variable I can use standalone deriving to create some simple instances

data Client
data Temporary
data Permanent

data Token ty where
  ClientToken :: Token Client
  TemporaryToken :: ByteString -> ByteString -> Token Temporary
  PermanentToken :: ByteString -> ByteString -> Token Permanent

deriving instance Eq (Token Client)
deriving instance Eq (Token Temporary)
deriving instance Eq (Token Permanent)

which appear to work perfectly in GHCi

> ClientToken == ClientToken
True
> TemporaryToken "" "foo" == TemporaryToken "" "bar"
False

When I try to compile I get a warning, though.

src/Network/HTTP/Conduit/OAuth/Types/Credentials.hs:72:1:
    Couldn't match type `Client' with `Temporary'
    Inaccessible code in
      a pattern with constructor
        TemporaryToken :: S8.ByteString
                          -> S8.ByteString -> Token Temporary,
      in an equation for `=='
    In the pattern: TemporaryToken a1 a2
    In an equation for `==':
        == (TemporaryToken a1 a2) (TemporaryToken b1 b2)
          = (((a1 == b1)) && ((a2 == b2)))
    When typechecking the code for  `=='
      in a standalone derived instance for `Eq (Token Client)':
      To see the code I am typechecking, use -ddump-deriv
    In the instance declaration for `Eq (Token Client)'

Which seems to be a buggy bit of the GADT deriving code (re: Haskell Inaccessible code bug? and https://ghc.haskell.org/trac/ghc/ticket/8128) but since it seems to have the right behavior I'd like to know

  1. Can I turn off these warnings with some -fno-warn-* flag? And, if possible
  2. Is there any problematic side effect to doing so?
Was it helpful?

Solution

I tested your example code in GHC 7.6.3 and at least there I get an actual compilation error instead of a warning in both GHCi and when compiling. It seems that the automatic instance deriving isn't smart enough to realize that it only needs to match a single constructor with the given GADT.

The following works though

data Client
data Temporary
data Permanent

data Token ty where
  ClientToken :: Token Client
  TemporaryToken :: ByteString -> ByteString -> Token Temporary
  PermanentToken :: ByteString -> ByteString -> Token Permanent

deriving instance Eq (Token ty)

But maybe your real use-case is more complex?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top