Yitzchak Gale gale at sefer.org
Wed Feb 21 09:36:16 EST 2007

Hi Alfonso,

You wrote:
>     Could not deduce (Synchronous s f11)
>       from the context (Synchronous s f1)
> \begin{code}
> class Synchronous s f1  where
>  mapSY          :: f1 a b   -> s a -> s b
>  delaySY         :: a        -> s a -> s a
>  sourceSY       :: f1 a a -> a    -> s a
>  sourceSY f s0 = o
>   where
>      o                  = delaySY s0 s
>      s                  = mapSY f o
> \end{code}
>
> Can anyone explain a bit further than GHC what am I doing wrong?

Every method of a multiparameter class must refer
to every parameter in its signature. Otherwise, there
is no way for the compiler to know which instance
of the class you want when you use the method.

There are two ways to get around this restriction.
One is to use a functional dependency:

class Synchronous s f1 | s -> f1 where

That promises that for each type s, you will
only define an instance Synchronous s f1
for at most a single type f1. Now, whenever
you mention s in a type signature, it is as if
you also mentioned f1.

If you can't keep that promise, then you will
have to use a phantom parameter. Change
the type of delaySY to

delaySY         :: f1 -> a -> s a -> s a

and ignore the f1 parameter when you implement
delaySY:

delaySY _ x y = ...

Then, when you use delaySY, you specify the
type f1 by writing:

delaySY (undefined :: T) ...

Regards,
Yitz