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

穿精又带淫゛_ 提交于 2019-12-05 05:12:48
Daniel Fischer

I was hoping GHC would be able to pull the Typeable constraint from the context on the Wrap constructor

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 derived

instance Eq (Wrapper a)

does not have an Eq constraint on the type variable 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

But 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 supplies

instance Typeable t => Typeable (Wrapper t)

but not an unconstrained

instance Typeable (Wrapper t)

and that unconstrained instance cannot be derived by GHC.

Hence you have to either provide a constrained

instance Typeable t => BothEqAndTypeable (Wrapper t)

or an unconstrained

instance Typeable (Wrapper t)

yourself.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!