本文介绍了我如何获得GHC在上下文中使用Typeable生成Data.Typeable实例的GADT?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 假设我有以下代码: { - #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 - >包装a 派生实例Eq(包装器a)派生实例Typeable1包装器 然后,下面的实例声明可以工作,没有 t 约束: 实例OnlyEq(Wrapper t) 我希望这样做。 但下面的实例声明不起作用: instance BothEqAndTypeable(Wrapper t) 自GHC - 我使用7.6.1 - 抱怨: 没有(Typeable t)的实例来自实例声明的超类可能的修正: add(Typeable t)添加到实例声明的上下文在`BothEqAndTypeable(Wrapper t)'$ b $的实例声明中b 在上下文中添加 Typeable t 当然可以。但添加以下实例也是如此: pre $ $ $ $ $ $ $ $ $ $ $ $ $ (Wrap x)`mkAppTy` typeOf x 有没有办法让GHC写这个后一个实例为了我?如果是这样,怎么样?如果不是,为什么不呢? 我希望GHC能够从 Typeable 约束> Wrap 构造函数,就像它使用 Eq 约束一样。 我认为我的问题归结为GHC明确禁止编写派生实例Typeable(Wrapper t)和标准( Typeable1 s,Typeable a)=> Typeable(sa)实例不能在内部寻找 sa 来找到可键入的a dictionary。解决方案 如果它有一个 Wrap 构造函数,它可以从中取出 Typeable 约束。 但它没有 Wrap 构造函数。 是 Eq 实例使用该值,所以它可以是 Wrap something ,其中 Wrap 构造函数使得包装类型的 Eq 字典可用,并且一切正常,或者它是⊥,然后一切都很好,评估 x == y 底部出。 请注意派生 实例方程(包装a) does not 有 Eq 约束类型变量 a 。 Prelude DerivT> (undefined :: Wrapper(Int - > Int))== undefined ***例外:Prelude.undefined Prelude DerivT> (undefined ::(Int→> Int))== undefined < interactive>:3:29:(Eq(Int - > Int)使用'=='可能的修正:为(Eq(Int - > Int))添加一个实例声明在表达式中:(undefined :: Int - > Int)== undefined 在'it'的等式中: it =(undefined :: Int - > Int)== undefined 但是 Typeable 实例不能使用该值,所以如果提供的值不是包装一些东西。 因此,派生的实例Typeable1 Wrapper 耗材 实例Typeable t => Typeable(Wrapper t) 但不是无限制的 实例Typeable(Wrapper t) 实例不能由GHC派生出来。 因此,您必须提供受限制的 instance Typeable t => BothEqAndTypeable(Wrapper t) 或不受约束的 $ b $ p 实例可类型化(Wrapper t) p> Suppose I have the following code:{-# LANGUAGE GADTs, DeriveDataTypeable, StandaloneDeriving #-}import Data.Typeableclass Eq t => OnlyEq tclass (Eq t, Typeable t) => BothEqAndTypeable tdata Wrapper a where Wrap :: BothEqAndTypeable a => a -> Wrapper aderiving instance Eq (Wrapper a)deriving instance Typeable1 WrapperThen, the following instance declaration works, without a constraint on t:instance OnlyEq (Wrapper t)and does what I expect it to do.But the following instance declaration doesn't work:instance BothEqAndTypeable (Wrapper t)since GHC - I'm using 7.6.1 - complains that:No instance for (Typeable t) arising from the superclasses of an instance declarationPossible fix: add (Typeable t) to the context of the instance declarationIn the instance declaration for `BothEqAndTypeable (Wrapper t)'Adding Typeable t to the context works, of course. But so does adding the following instance:instance Typeable (Wrapper t) where typeOf (Wrap x) = typeOf1 (Wrap x) `mkAppTy` typeOf xIs there a way to get GHC to write this latter instance for me? If so, how? If not, why not? I was hoping GHC would be able to pull the Typeable constraint from the context on the Wrap constructor, just as it did with the Eq constraint.I think that my problems boils down to the fact that GHC explicitly disallows writing deriving instance Typeable (Wrapper t), and the standard (Typeable1 s, Typeable a) => Typeable (s a) instance can't 'look inside' s a to find a Typeable a dictionary. 解决方案 If it had a Wrap constructor, it could pull the Typeable constraint from it.But it doesn't have a Wrap constructor.The difference is that the Eq instance uses the value, so it's either a Wrap something, where the Wrap constructor makes the Eq dictionary for the wrapped type available, and everything is fine, or it's ⊥, and then everything is fine too, evaluating x == y bottoms out.Note that the derivedinstance Eq (Wrapper a)does not have an Eq constraint on the type variable a.Prelude DerivT> (undefined :: Wrapper (Int -> Int)) == undefined*** Exception: Prelude.undefinedPrelude 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) == undefinedBut the Typeable instance must not make use of the value, so there's no bottoming out if the supplied value isn't a Wrap something.Thus the derived instance Typeable1 Wrapper suppliesinstance Typeable t => Typeable (Wrapper t)but not an unconstrainedinstance Typeable (Wrapper t)and that unconstrained instance cannot be derived by GHC.Hence you have to either provide a constrainedinstance Typeable t => BothEqAndTypeable (Wrapper t)or an unconstrainedinstance Typeable (Wrapper t)yourself. 这篇关于我如何获得GHC在上下文中使用Typeable生成Data.Typeable实例的GADT?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-18 22:25