On 9/7/07, Levi Stephen <[EMAIL PROTECTED]> wrote: > I'm after some help understanding either what I'm doing wrong, or why this > error > occurs. > > I have a data type: > > > data T a = forall b. (Show b) => T b a
I should first point out that by mentioning b only on the RHS, you've defined an existential type. If that's what you intended, then fine; if not, the type you probably wanted was: data (Show b) => T b a = T b a which makes most of these problems go away. > and I want to use/extract 'b' from this. > > > extShow (T b _) = b > > This gives the following compilation error: > > extest.hs:5:0: > Inferred type is less polymorphic than expected > Quantified type variable `b' escapes > When checking an existential match that binds > $dShow :: {Show b} > b :: b > The pattern(s) have type(s): T t > The body has type: b > In the definition of `extShow': extShow (T b _) = b For reasons that I don't claim to completely understand, the compiler doesn't allow "raw" existential types (such as the type of b) to escape from their binding scope. See my final comment for a potential workaround. > I tried adding a type signature: > > > extShow' :: (Show b) => T a -> b > > extShow' (T b _) = b The type you've declared is: extShow' :: forall a b. (Show b) => T a -> b which carries the implicit claim that for *any* instance of Show the context desires, we can return a value of that type. This contradicts the data type, which only contains a value of some *specific* type. What you really want is something along the lines of: extShow' :: forall a. exists b. (Show b) => T a -> b -- not valid Haskell! which unfortunately isn't allowed. > It seems (to newbie me ;) ) like it should be possible to extract the first > part > of T, and deduce that it is an instance of the class 'Show'. > > The following seems ok: > > > doShow (T b _) = putStrLn (show b) You can generalise this to arbitrary functions as follows: extShowWith :: (forall b. (Show b) => b -> c) -> T a -> c extShowWith f (T b _) = f b doShow = extShowWith (putStrLn . show) This works because f is required to accept *any* Show instance as an argument type, and so is happy to work for whatever particular type b happens to inhabit. Stuart Cook _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe