QuantifiedConstraint with InstanceSig compiles (surprise) but does nothing useful
Summary
Should this compile? (The InstanceSig
is rejected without the QuantifiedConstraint
at the instance
constraint.) If so, can it do anything useful? (Because it doesn't achieve what it appears.)
Steps to reproduce
-- attempt at a constrained Functor-like class
data Set a = NilSet | ConsSet a (Set a) deriving (Eq, Show, Read)
class WFT c_a where -- Well-Formed Type
instance Eq a => WFT (Set a)
{-# LANGUAGE InstanceSigs, QuantifiedConstraints, UndecidableInstances #-}
class WFTQFunctor f where
wftQfmap :: (WFT (f a), WFT (f b)) => (a -> b) -> f a -> f b
instance (forall b. (WFT (Set b) => Eq b)) => WFTQFunctor Set where -- QuantifiedConstraint
wftQfmap :: (Eq a, Eq b) => (a -> b) -> (Set a) -> (Set b) -- yay -- InstanceSig
wftQfmap f xss = fmapSet f xss
-- fmap over a Set, squishing out duplicates
fmapSet :: (Eq a, Eq b ) => (a -> b) -> Set a -> Set b
fmapSet f NilSet = NilSet
fmapSet f (ConsSet x xs) = uqCons (f x) (fmapSet f xs)
uqCons fx fxs | sElem fx fxs = fxs
| otherwise = ConsSet fx fxs
sElem fx NilSet = False
sElem fx (ConsSet fy fys) = fx == fy || sElem fx fys
This compiles, with a MonoLocalBinds
warning about the instance (...) => WFTQFunctor Set
, presumably because of the QuantifiedConstraint
:
* The constraint `WFT (Set b)' matches
instance Eq a => WFT (Set a)
-- Defined at ...
This makes type inference for inner bindings fragile;
either use MonoLocalBinds, or simplify it using the instance
* In the instance declaration for `WFTQFunctor Set'
(BTW the InstanceSig
is unnecessary. I'm merely demonstrating the QuantifiedConstraint
is inferring the (Eq a, Eq b)
so it can call fmapSet
. Switching on MonoLocalBinds
makes the warning go away, but doesn't affect the behaviour.)
Expected behavior
Since it compiles with the (Eq a, Eq b) =>
accepted on the InstanceSig
, I expect wftQfmap
to be callable on a Set
for an Eq
element type. But:
*> wftQfmap toUpper (mySet :: Set Char)
<interactive>:5:1: error:
* Could not deduce (Eq b) arising from a use of `wftQfmap'
from the context: WFT (Set b)
bound by a quantified context at <interactive>:5:1-36
Possible fix: add (Eq b) to the context of a quantified context
* In the expression: wftQfmap toUpper (mySet :: Set Char)
In an equation for `it': it = wftQfmap toUpper (mySet :: Set Char)
It seems wftQfmap
cannot be called for any Set
type.
Environment
- GHC version used: 8.10.2
Optional:
- Operating System: Windows
- System Architecture: