
Hi all, I'm trying to use the State Monad to help implement a digital filter: 17 newtype Filter e a = F { 18 runFilter :: a -> EitherT e (State FilterState) a 19 } deriving (Monad, MonadState FilterState) but I'm getting these compiler errors: Filter.hs:19:14: Can't make a derived instance of `Monad (Filter e)' (even with cunning newtype deriving): cannot eta-reduce the representation type enough In the newtype declaration for `Filter' Filter.hs:19:21: Can't make a derived instance of `MonadState FilterState (Filter e)' (even with cunning newtype deriving): cannot eta-reduce the representation type enough In the newtype declaration for `Filter' If I change the code to this: 17 newtype Filter e a = F { * 18 runFilter :: EitherT e (State FilterState) a ** * 19 } deriving (Monad, MonadState FilterState) it compiles, but I can't figure out how I'd feed the input to the filter, in that case. In comparing this to the tricks used in constructing the State Monad based version of the `Parser' type, I notice that Parser gets around this issue, by having the input (i.e. - input stream) be a part of the initial state, but I'm not sure that's appropriate for a digital filter. Thanks, -db

On Sat, Oct 8, 2011 at 4:28 PM, Captain Freako
17 newtype Filter e a = F { * 18 runFilter :: EitherT e (State FilterState) a ** * 19 } deriving (Monad, MonadState FilterState)
it compiles, but I can't figure out how I'd feed the input to the filter, in that case.
Input to Filter would be modeled with: 'a -> Filter e b'. I would rename your 'runFilter' to 'unFilter', then define a function 'runFilter' accepting an initial FilterState. Regards, - db

Hi David,
Thanks for the reply.
In trying to follow your advice, I arrived at this code:
17 newtype Filter e a = F {
18 runFilter :: EitherT e (State FilterState) a
19 } deriving (Monad, MonadState FilterState)
20
21 applyFilter :: Filter e a -> FilterState -> a -> (Either e a,
FilterState)
22 applyFilter f s x = runState (runEitherT (runFilter f)) s
which compiles ok, but I don't know where to put the `x' on the right side
of the `=' in line 22. That is, I still don't understand how I'm supposed to
feed the input, `x', into the filter.
Thanks,
-db
On Sat, Oct 8, 2011 at 5:27 PM, David Barbour
On Sat, Oct 8, 2011 at 4:28 PM, Captain Freako
wrote: 17 newtype Filter e a = F { * 18 runFilter :: EitherT e (State FilterState) a ** * 19 } deriving (Monad, MonadState FilterState)
it compiles, but I can't figure out how I'd feed the input to the filter, in that case.
Input to Filter would be modeled with: 'a -> Filter e b'.
I would rename your 'runFilter' to 'unFilter', then define a function 'runFilter' accepting an initial FilterState.
Regards,
- db

On Sun, Oct 9, 2011 at 7:57 PM, Captain Freako
21 applyFilter :: Filter e a -> FilterState -> a -> (Either e a, FilterState) 22 applyFilter f s x = runState (runEitherT (runFilter f)) s
I still don't understand how I'm supposed to feed the input, `x', into the filter.
In 'Filter e a', a is an output type, not an input type. If you want inputs, you'll need constructors of the form (a -> Filter e b). This might be closer to what you're looking for: applyFilter :: FilterState -> (a -> Filter e b) -> a -> (Either e b, FilterState) applyFilter s f x = runState (runEitherT (runFilter (f x))) s The burden of receiving input is then shifted to the functions that create 'Filter' operations. If you really want the input type to be part of the Filter type definition, you'll need to use arrows instead of monads.

On Oct 9, 2011 11:17 PM, "David Barbour"
If you really want the input type to be part of the Filter type definition, you'll need to use arrows instead of monads.
I wouldn't say that. You just need an extra type parameter. That doesn't mean it can't be a monad. In fact, wrapping ReaderT around the existing representation gives us exactly the monad we probably want. That said, I think it is likely to be more useful in this context either as it is or as an arrow. I just want to point out that it can still be a monad even if it is an arrow. - Jake

On Sat, Oct 08, 2011 at 04:28:34PM -0700, Captain Freako wrote:
Hi all,
I'm trying to use the State Monad to help implement a digital filter:
(a -> EitherT e (State FilterState) a) is definitely not monadic. There is an 'a' in a negative position (to the left of an odd number of arrows) so it is not even a Functor. But I think you want to have the 'a ->' part separate. I might do something like newtype FilterM e a = F { unFilterM :: EitherT e (State FilterState) a } deriving (Functor, Applicative, Monad, MonadState FilterState) type Filter e a b = a -> FilterM e b That is, a Filter is a function from a to b, which can abort with an error of type e and maintains a FilterState. Then you can chain Filters using (>=>): if f1 :: Filter e a b f2 :: Filter e b c then f1 >=> f2 :: Filter e a c is a Filter which does first f1 then f2. Alternatively, if you wanted to use an Arrow interface you could define import Control.Arrow type Filter e a b = Kleisli (FilterM e) a b -Brent

Your filter type isn't a Monad.
In particular
bind :: (a -> EitherT e (State FilterState) a) -> (a -> b -> EitherT e
(State FilterState) b) -> b -> EitherT e (State FilterState) b
can't be implemented, as you have no place to grab an 'a' to pass to the
initial computation.
If you fix the input type, you can do
newtype Filter r e a = F {
runFilter :: r -> EitherT e (State FilterState) a
}
which is isomorphic to
newtype Filter r e a = F {
runFilter :: ReaderT r (EitherT e (State FilterState)) a
}
which newtype deriving will be able to deal with easily.
-- ryan
On Sat, Oct 8, 2011 at 4:28 PM, Captain Freako
Hi all,
I'm trying to use the State Monad to help implement a digital filter:
17 newtype Filter e a = F { 18 runFilter :: a -> EitherT e (State FilterState) a 19 } deriving (Monad, MonadState FilterState)
but I'm getting these compiler errors:
Filter.hs:19:14: Can't make a derived instance of `Monad (Filter e)' (even with cunning newtype deriving): cannot eta-reduce the representation type enough In the newtype declaration for `Filter'
Filter.hs:19:21: Can't make a derived instance of `MonadState FilterState (Filter e)' (even with cunning newtype deriving): cannot eta-reduce the representation type enough In the newtype declaration for `Filter'
If I change the code to this:
17 newtype Filter e a = F { * 18 runFilter :: EitherT e (State FilterState) a ** * 19 } deriving (Monad, MonadState FilterState)
it compiles, but I can't figure out how I'd feed the input to the filter, in that case.
In comparing this to the tricks used in constructing the State Monad based version of the `Parser' type, I notice that Parser gets around this issue, by having the input (i.e. - input stream) be a part of the initial state, but I'm not sure that's appropriate for a digital filter.
Thanks, -db
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (5)
-
Brent Yorgey
-
Captain Freako
-
David Barbour
-
Jake McArthur
-
Ryan Ingram