yat*_*975 7 haskell ghc derived-instances 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 -> Wrapper a
deriving instance Eq (Wrapper a)
deriving instance Typeable1 Wrapper
Run Code Online (Sandbox Code Playgroud)
然后,以下实例声明工作,没有约束t:
instance OnlyEq (Wrapper t)
Run Code Online (Sandbox Code Playgroud)
并做我期望它做的事情.
但是以下实例声明不起作用:
instance BothEqAndTypeable (Wrapper t)
Run Code Online (Sandbox Code Playgroud)
自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)'
Run Code Online (Sandbox Code Playgroud)
Typeable t当然,添加到上下文工作.但添加以下实例也是如此:
instance Typeable (Wrapper t) where
typeOf (Wrap x) = typeOf1 (Wrap x) `mkAppTy` typeOf x
Run Code Online (Sandbox Code Playgroud)
有没有办法让GHC为我写这个后一个实例?如果是这样,怎么样?如果没有,为什么不呢?
我希望GHC能够Typeable从Wrap构造函数的上下文中拉出约束,就像它对Eq约束一样.我认为我的问题归结为GHC明确禁止写作这一事实deriving instance Typeable (Wrapper t),而标准(Typeable1 s, Typeable a) => Typeable (s a)实例无法"查找内部" s a来查找Typeable a字典.
我希望GHC能够
Typeable从Wrap构造函数的上下文中拉出约束
如果它有一个Wrap构造函数,它可以Typeable从中拉出约束.
但它没有Wrap构造函数.
不同之处在于Eq实例使用了值,所以它是a Wrap something,Wrap构造函数使得Eq包装类型的字典可用,一切都很好,或者它是?,然后一切都很好,评估x == y底部.
注意派生
instance Eq (Wrapper a)
Run Code Online (Sandbox Code Playgroud)
并不能有一个Eq对类型变量的约束a.
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
Run Code Online (Sandbox Code Playgroud)
但是Typeable实例不能使用该值,因此如果提供的值不是a,则不会触底Wrap something.
因此衍生的instance Typeable1 Wrapper供应
instance Typeable t => Typeable (Wrapper t)
Run Code Online (Sandbox Code Playgroud)
但不是不受约束的
instance Typeable (Wrapper t)
Run Code Online (Sandbox Code Playgroud)
并且GHC不能导出无约束的实例.
因此,您必须提供约束
instance Typeable t => BothEqAndTypeable (Wrapper t)
Run Code Online (Sandbox Code Playgroud)
或者不受限制的
instance Typeable (Wrapper t)
Run Code Online (Sandbox Code Playgroud)
你自己.
| 归档时间: |
|
| 查看次数: |
901 次 |
| 最近记录: |