Multiparameter class error

Hi, I'm a newbie to multiparameter classes and I'm getting this error from GHC when compiling the following class definition: Could not deduce (Synchronous s f11) from the context (Synchronous s f1) arising from use of `delaySY' Possible fix: add (Synchronous s f11) to the class or instance method `sourceSY' In the expression: delaySY s0 s In the definition of `o': o = delaySY s0 s In the definition of `sourceSY': sourceSY f s0 = o where o = delaySY s0 s s = mapSY f \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? Thanks, Alfonso Acosta

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

Thanks, the functional dependency solved the problem
On 2/21/07, Yitzchak Gale
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
participants (2)
-
Alfonso Acosta
-
Yitzchak Gale