type class problem
Martin Sulzmann
sulzmann at comp.nus.edu.sg
Wed Oct 1 17:37:11 EDT 2003
There's another possible fix which makes use of scoped variables.
instance (RT r1 t1, RT r2 t2, TPair t t1 t2) => RT (RPair r1 r2) t where
rtId (RPair r1 r2) t = "RT (RPair " ++ rtId r1 t1 ++ " " ++ rtId r2 t2 ++")"
where (t1::t1,t2::t2) = prj t
^^^^^^^^^^^^^^
scoped variables
Martin
>
> Dean Herington wrote:
> > Can someone explain why the following doesn't work?
>
> > {-# OPTIONS -fglasgow-exts #-}
>
> > class R r where
> > rId :: r -> String
>
> > class (R r) => RT r t where
> > rtId :: r -> t -> String
>
> > data RPair r1 r2 = RPair r1 r2
>
> > instance (R r1, R r2) => R (RPair r1 r2) where
> > rId (RPair r1 r2) = "RPair " ++ rId r1 ++ " " ++ rId r2
>
> > class TPair t t1 t2 where
> > prj :: t -> (t1,t2)
> > inj :: (t1,t2) -> t
>
> > instance (RT r1 t1, RT r2 t2, TPair t t1 t2) => RT (RPair r1 r2) t where
> > rtId (RPair r1 r2) t = "RT (RPair " ++ rtId r1 t1 ++ " " ++ rtId r2 t2 ++")"
> > where (t1,t2) = prj t
>
> You need a functional dependency. For example:
>
> class TPair t t1 t2 | t->t1 t2 where
> prj :: t -> (t1,t2)
> inj :: (t1,t2) -> t
>
> with this definition, the typechecker is satisfied.
>
> Without the dependency, the compiler assumes that there may be several
> instances:
> TPair t t1 t2
> and
> TPair t t1' t2'
>
> You claimed that RT r1 t1 and RT r2 t2 holds. But you didn't promise
> that RT r1 t1' and RT r2 t2' will also hold. In other words,
> (RT r1 t1, RT r2 t2, TPair t t1 t2)
> reads as
> (exists t1 t2. RT r1 t1, RT r2 t2, TPair t t1 t2)
> rather than
> (forall t1 t2. RT r1 t1, RT r2 t2, TPair t t1 t2)
> (which you need to guarantee that the definition of (t1,t2) = prj t
> can be typechecked). Notice that forall is _inside_ of parentheses,
> on the assumption side (the negative side).
>
> _______________________________________________
> Haskell mailing list
> Haskell at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell
More information about the Haskell
mailing list