(forall x. c x, forall x. d x) is not equivalent to forall x. (c x, d x)
Consider the following code:
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
module Foo where
import Data.Kind
type family F a :: Type -> Type
newtype WrappedF a b = WrapF (F a b)
deriving instance Functor (F a) => Functor (WrappedF a)
deriving instance Foldable (F a) => Foldable (WrappedF a)
deriving instance Traversable (F a) => Traversable (WrappedF a)
data SomeF b = forall a. MkSomeF (WrappedF a b)
deriving instance (forall a. Functor (WrappedF a)) => Functor SomeF
deriving instance (forall a. Foldable (WrappedF a)) => Foldable SomeF
deriving instance ( forall a. Functor (WrappedF a)
, forall a. Foldable (WrappedF a)
, forall a. Traversable (WrappedF a)
) => Traversable SomeF
This typechecks. However, the last Traversable SomeF
is a bit unfortunate in that is uses three separate forall a.
s. I attempted to factor this out, like so:
deriving instance (forall a. ( Functor (WrappedF a)
, Foldable (WrappedF a)
, Traversable (WrappedF a)
)) => Traversable SomeF
But then the file no longer typechecked!
$ /opt/ghc/8.6.1/bin/ghc Foo.hs
[1 of 1] Compiling Foo ( Foo.hs, Foo.o )
Foo.hs:21:1: error:
• Could not deduce (Functor (F a))
arising from the superclasses of an instance declaration
from the context: forall a.
(Functor (WrappedF a), Foldable (WrappedF a),
Traversable (WrappedF a))
bound by the instance declaration at Foo.hs:(21,1)-(24,52)
• In the instance declaration for ‘Traversable SomeF’
|
21 | deriving instance (forall a. ( Functor (WrappedF a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
Foo.hs:21:1: error:
• Could not deduce (Foldable (F a))
arising from the superclasses of an instance declaration
from the context: forall a.
(Functor (WrappedF a), Foldable (WrappedF a),
Traversable (WrappedF a))
bound by the instance declaration at Foo.hs:(21,1)-(24,52)
• In the instance declaration for ‘Traversable SomeF’
|
21 | deriving instance (forall a. ( Functor (WrappedF a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
Foo.hs:21:1: error:
• Could not deduce (Traversable (F a1))
arising from a use of ‘traverse’
from the context: forall a.
(Functor (WrappedF a), Foldable (WrappedF a),
Traversable (WrappedF a))
bound by the instance declaration at Foo.hs:(21,1)-(24,52)
or from: Applicative f
bound by the type signature for:
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> SomeF a -> f (SomeF b)
at Foo.hs:(21,1)-(24,52)
• In the second argument of ‘fmap’, namely ‘(traverse f a1)’
In the expression: fmap (\ b1 -> MkSomeF b1) (traverse f a1)
In an equation for ‘traverse’:
traverse f (MkSomeF a1) = fmap (\ b1 -> MkSomeF b1) (traverse f a1)
When typechecking the code for ‘traverse’
in a derived instance for ‘Traversable SomeF’:
To see the code I am typechecking, use -ddump-deriv
|
21 | deriving instance (forall a. ( Functor (WrappedF a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
Richard suspects that this is a bug in the way quantified constraints expands superclasses, so I decided to post it here.
Trac metadata
Trac field | Value |
---|---|
Version | 8.5 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler (Type checker) |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |