"A lazy (~) pattern cannot bind existential type variables"?

What is the reasoning behind the ghc restriction that "A lazy (~) pattern cannot bind existential type variables"? This error came up for me in the following code: -- | Add a continuation. data WithCont h b c = forall a. WC (h b a) (a -> c) instance Functor (WithCont h b) where fmap g ~(WC f k) = WC f (fmap g k) The error message: A lazy (~) pattern cannot bind existential type variables `a' is a rigid type variable bound by the constructor `WC' at Data/Zip/FoldL.hs:66:11 In the pattern: ~(WC f k) I also tried this variation: instance Functor (WithCont h b) where fmap g wc = WC f (fmap g k) where WC f k = wc and got this message: My brain just exploded. I can't handle pattern bindings for existentially-quantified constructors. Instead, use a case-expression, or do-notation, to unpack the constructor. In the binding group for WC f k In a pattern binding: WC f k = wc I can work around these limitations by using a lambda: instance Functor (WithCont h b) where fmap g = \ (WC f k) -> WC f (fmap g k) which I believe is equivalent. Please correct me if I'm wrong here. For infix definitions like (<*>), however, this work-around is less pleasant. For instance, (<*>) = \ (WC hf hk) (WC xf xk) -> WC (hf `zip` xf) (\ (a,a') -> (hk a) (xk a')) instead of the prettier but forbidden ~(WC hf hk) <*> ~(WC xf xk) = WC (hf `zip` xf) (\ (a,a') -> (hk a) (xk a')) If you're curious what these definitions are about, see http://conal.net/blog/posts/enhancing-a-zip/ . Thanks, - Conal
participants (1)
-
Conal Elliott