[英]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.