4

给定一个GADT由幻像变量索引的索引,我可以使用独立派生来创建一些简单的实例

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)

这似乎在 GHCi 中完美运行

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

但是,当我尝试编译时,会收到警告。

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)'

这似乎是 GADT 派生代码的一个错误位(re: Haskell Inaccessible code bug? and https://ghc.haskell.org/trac/ghc/ticket/8128)但因为它似乎有正确的行为我'我想知道

  1. -fno-warn-*我可以用一些标志关闭这些警告吗?并且,如果可能的话
  2. 这样做有什么问题的副作用吗?
4

1 回答 1

4

我在 GHC 7.6.3 中测试了您的示例代码,至少在那里我得到了一个实际的编译错误,而不是 GHCi 和编译时的警告。似乎自动实例派生不够聪明,无法意识到它只需要将单个构造函数与给定的 GADT 匹配。

以下工作虽然

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)

但也许你的真实用例更复杂?

于 2013-11-12T21:06:38.853 回答