簡體   English   中英

如何讓GHC為上下文中具有Typeable的GADT生成Data.Typeable實例?

[英]How can I get GHC to generate instances of Data.Typeable for GADTs with Typeable in the context?

假設我有以下代碼:

{-# LANGUAGE GADTs, DeriveDataTypeable, StandaloneDeriving #-}
import Data.Typeable

class Eq t => OnlyEq t
class (Eq t, Typeable t) => BothEqAndTypeable t

data Wrapper a where
    Wrap :: BothEqAndTypeable a => a -> Wrapper a

deriving instance Eq (Wrapper a)
deriving instance Typeable1 Wrapper

然后,以下實例聲明工作, 沒有t的約束:

instance OnlyEq (Wrapper t)

並做我期望它做的事情。


但是以下實例聲明不起作用:

instance BothEqAndTypeable (Wrapper t)

自GHC - 我使用7.6.1 - 抱怨說:

No instance for (Typeable t)
  arising from the superclasses of an instance declaration
Possible fix:
  add (Typeable t) to the context of the instance declaration
In the instance declaration for `BothEqAndTypeable (Wrapper t)'

當然,將Typeable t添加到上下文中。 但添加以下實例也是如此:

instance Typeable (Wrapper t) where
    typeOf (Wrap x) = typeOf1 (Wrap x) `mkAppTy` typeOf x

有沒有辦法讓GHC為我寫這個后一個實例? 如果是這樣,怎么樣? 如果沒有,為什么不呢?

我希望GHC能夠從Wrap構造函數的上下文中拉出Typeable約束,就像它對Eq約束一樣。 我認為我的問題歸結為GHC明確禁止編寫deriving instance Typeable (Wrapper t)這一事實,而標准(Typeable1 s, Typeable a) => Typeable (sa)實例不能'查找' sa來查找一個可Typeable a字典。

我希望GHC能夠從Wrap構造函數的上下文中提取Typeable約束

如果它有一個Wrap構造函數,它可以Typeable拉出Typeable約束。

但它沒有Wrap構造函數。

不同之處在於Eq實例使用了值,所以它是一個Wrap something ,其中Wrap構造函數使得包裝類型的Eq字典可用,一切都很好,或者它是 ,然后一切都很好,評估x == y最低點。

注意派生

instance Eq (Wrapper a)

在類型變量a沒有 Eq約束。

Prelude DerivT> (undefined :: Wrapper (Int -> Int)) == undefined
*** Exception: Prelude.undefined
Prelude DerivT> (undefined :: (Int -> Int)) == undefined

<interactive>:3:29:
    No instance for (Eq (Int -> Int)) arising from a use of `=='
    Possible fix: add an instance declaration for (Eq (Int -> Int))
    In the expression: (undefined :: Int -> Int) == undefined
    In an equation for `it':
        it = (undefined :: Int -> Int) == undefined

但是Typeable實例不能使用該值,因此如果提供的值不是Wrap something ,則不會觸底。

因此派生的instance Typeable1 Wrapper供應

instance Typeable t => Typeable (Wrapper t)

但不是不受約束的

instance Typeable (Wrapper t)

並且GHC不能導出無約束的實例。

因此,您必須提供約束

instance Typeable t => BothEqAndTypeable (Wrapper t)

或者不受限制的

instance Typeable (Wrapper t)

你自己。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM