[Haskell-cafe] Hiding "growing" state using existentials.

Tom Schouten tom at zwizwa.be
Tue Aug 16 01:37:46 CEST 2011


Dear Cafe,

I'm building an abstraction for representing sequences as difference
equations, storing initial values and update equation.

I have something that resembles a Monad, but has an extra state
parameter s that "grows" on _join or _bind, so I can't simply create
an instance Monad (Sig s).

 > {-# LANGUAGE ExistentialQuantification #-}

 > data Sig s a = Sig s (s -> (a, s))

 > _join :: (Sig s1 (Sig s2 a)) -> Sig (s1,s2) a
 > _join (Sig i1 u1) = Sig (i1, i2) u12 where
 >   ((Sig i2 _), _) = u1 i1
 >   u12 (s1, s2) = (a, (s1', s2')) where
 >     ((Sig _ u2), s1') = u1 s1
 >     (a, s2')          = u2 s2

 > _fmap :: (a -> b) -> Sig s a -> Sig s b
 > _fmap f (Sig s0 u) = Sig s0 u' where
 >   u' s = (f a, s') where
 >     (a, s') = u s

 > _return x = Sig () $ \() -> (x, ())

 > _bind :: (Sig s1 a) -> (a -> Sig s2 b) -> (Sig (s1,s2) b)
 > m `_bind` g = _join ((_fmap g) m)


I try to hide the state parameter using existential quantification.

 > data Signal a = forall s. Signal (Sig s a)

This approach works for defining Functor and Applicative instances,
but I can't seem to find a way to obtain an unwrapped version of f
that can be passed to _bind to implement the Monad instance's (>>=).
The following returns:

     Couldn't match type `t' with `Sig s1 b'
       `t' is a rigid type variable bound by
           the inferred type of f' :: a -> t
           at /home/tom/meta/ssm/SigHC.lhs:52:7
     In the expression: mb
     In a case alternative: Signal mb -> mb
     In the expression: case (f a) of { Signal mb -> mb }

 > instance Monad Signal where
 >   return = Signal . _return
 >   (>>=) (Signal ma) f = Signal $ ma `_bind` f' where
 >     f' a = case (f a) of
 >       Signal mb -> mb

Any tips on how to work around this?

Cheers,
Tom




More information about the Haskell-Cafe mailing list