
Alfonso Acosta wrote:
I tried the existential approach when it was previously suggested by Chris, but the problem is that, for some Source instances calling methods from HDPrimType within supplySig is not enough. Thus, it doesn't work with existentials due to their limitations.
I see. The typechecker is right then: one can't write
supplySig :: (PortIndex ix, HDPrimType a) => HDSignal a -> ix -> d -> d
because supplySig is not parametric in 'a': supplySig needs to know more than just the membership of 'a' in HDPrimType. It needs a more refined constraint. So, the class hierarchy has to change, for example, as follows
data HDSignal a = HDSignal data HDSignal' d = forall a. DestPort' d a => HDSignal' (HDSignal a) class HDPrimType a where class PortIndex a where
class SourcePort s where -- Plug an external signal to the port plugSig :: (PortIndex ix, DestPort d) =>ix -> s -> (HDSignal' d -> b) -> b
class DestPort d where supplySig :: (PortIndex ix) => HDSignal' d -> ix -> d -> d supplySig (HDSignal' sig) = supplySig' sig
class HDPrimType a => DestPort' d a where -- Supply a signal to the port supplySig' :: (PortIndex ix) => HDSignal a -> ix -> d -> d
-- Connect providing indexes
connectIx :: (SourcePort s, PortIndex six, DestPort d, PortIndex dix) => six -> s -> dix -> d -> d connectIx six s dix d = plugSig six s $ (push2 supplySig) dix d
push2 :: (a -> b -> c -> d) -> b -> c -> a -> d push2 f = (\b c a -> f a b c)