<p>Hi John,</p>
<div>Thanks for this reply:<br></div>
<div>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">
<div>Date: Tue, 18 Oct 2011 14:05:22 +1030<br>From: John Lask &lt;<a href="mailto:jvlask@hotmail.com">jvlask@hotmail.com</a>&gt;<br>Subject: Re: [Haskell-cafe] How to implement a digital filter, using<br>       Arrows?<br>
To: <a href="mailto:haskell-cafe@haskell.org">haskell-cafe@haskell.org</a><br>Message-ID: &lt;BLU0- <br><a href="mailto:SMTP384394452FD2750FBE3BCFCC6E50@phx.gbl">SMTP384394452FD2750FBE3BCFCC6E50@phx.gbl</a>&gt;<br>Content-Type: text/plain; charset=&quot;ISO-8859-1&quot;; format=flowed</div>

<p> </p>
<p>your function corresponds with Control.Arrow.Transformer.Automaton. If<br>you frame your function is such most of your plumbing is taken care of.</p></blockquote>Following your advice, I arrived at:</div>
<p><font face="courier new,monospace">  1 {-# LANGUAGE Arrows, GeneralizedNewtypeDeriving, FlexibleContexts #-}<br>  2 <br>  3 module Filter (<br>  4     FilterState<br>  5   , Filter<br>  6   , applyFilter<br>  7   , convT<br>
  8 ) where<br>  9 <br> 10 import EitherT<br> 11 import Control.Monad<br> 12 import Control.Monad.State<br> 13 import Control.Arrow<br> 14 import Control.Arrow.Operations<br> 15 import Control.Arrow.Transformer<br> 16 import Control.Arrow.Transformer.All<br>
 17 import Data.Stream as DS (fromList, toList)<br> 18 <br> 19 -- tap weights, `as&#39; and `bs&#39;, are being made part of the filter state, in<br> 20 -- order to accomodate adaptive filters (i.e. - DFEs).<br> 21 data FilterState a = FilterState {<br>
 22     as   :: [a] -- transfer function denominator coefficients<br> 23   , bs   :: [a] -- transfer function numerator coefficients<br> 24   , taps :: [a] -- current delay tap stored values<br> 25   }<br> 26 <br> 27 -- Future proofing the implementation, using the `newtype&#39; trick.<br>
 28 newtype Filter b c = F {<br> 29     runFilter :: (b, FilterState b) -&gt; (c, FilterState b)<br> 31   }<br> 32 <br> 33 -- Time domain convolution filter (FIR or IIR),<br> 34 -- expressed in direct form 2<br> 35 convT :: (Num b) =&gt; Filter b b<br>
 36 convT = F $ \(x, s) -&gt;<br> 37     let wk = (x - sum [a * t | (a, t) &lt;- zip (tail $ as s) (taps s)])<br> 38         newTaps = wk : ((reverse . tail . reverse) $ taps s)<br> 39         s&#39; = s {taps = newTaps}<br>
 40         y  = sum [b * w | (b, w) &lt;- zip (bs s) (wk : (taps s))]<br> 41     in (y, s&#39;)<br> 42 <br> 43 -- Turn a filter into an Automaton, in order to use the built in plubming<br> 44 -- of Arrows to run the filter on an input.<br>
 45 filterAuto :: (ArrowApply a) =&gt; Filter b c -&gt; FilterState b -&gt; Automaton a (e, b) c<br> 46 filterAuto f s = Automaton a where<br> 47     a = proc (e, x) -&gt; do<br> 48         (y, s&#39;) &lt;- arr (runFilter f) -&lt; (x, s)<br>
 49         returnA -&lt; (y, filterAuto f s&#39;)<br> 50 <br> 53 applyFilter :: Filter b c -&gt; FilterState b -&gt; [b] -&gt; ([c], FilterState b)<br> 54 applyFilter f s =<br> 55     let a = filterAuto f s<br> 56     in proc xs -&gt; do<br>
 57         ys &lt;- runAutomaton a -&lt; ((), DS.fromList xs)<br> 58         s&#39; &lt;- (|fetch|)<br> 59         returnA -&lt; (DS.toList ys, s&#39;)<br> 60 </font></p>
<p>which gave me this compile error:</p>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">
<p>Filter.hs:58:16:<br>    Could not deduce (ArrowState (FilterState b) (-&gt;))<br>      from the context ()<br>      arising from a use of `fetch&#39; at Filter.hs:58:16-20<br>    Possible fix:<br>      add (ArrowState (FilterState b) (-&gt;)) to the context of<br>
        the type signature for `applyFilter&#39;<br>      or add an instance declaration for<br>         (ArrowState (FilterState b) (-&gt;))<br>    In the expression: fetch<br>    In the expression:<br>        proc xs -&gt; do { ys &lt;- runAutomaton a -&lt; ((), fromList xs);<br>
                        s&#39; &lt;- (|fetch |);<br>                        returnA -&lt; (toList ys, s&#39;) }<br>    In the expression:<br>        let a = filterAuto f s<br>        in<br>          proc xs -&gt; do { ys &lt;- runAutomaton a -&lt; ((), fromList xs);<br>
                          s&#39; &lt;- (|fetch |);<br>                          .... }</p></blockquote>
<p>So, I made this change:</p>
<p><font face="courier new,monospace"> 51 applyFilter :: <strong>(ArrowState (FilterState b) (-&gt;)) =&gt;</strong> Filter b c -&gt; FilterState b -&gt; [b] -&gt;<br> 52                                                     ([c], FilterState b)</font></p>

<p>And that compiled. However, when I tried to test my new filter with:</p>
<p><font face="courier new,monospace">&gt; let s = FilterState [1,0,0] [0.7, 0.2, 0.1] [0, 0, 0]<br>&gt; applyFilter convT s [1,0,0,0,0]</font></p>
<p>I got:</p>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">
<p>&lt;interactive&gt;:1:0:<br>    No instance for (ArrowState (FilterState Double) (-&gt;))<br>      arising from a use of `applyFilter&#39; at &lt;interactive&gt;:1:0-30<br>    Possible fix:<br>      add an instance declaration for<br>
      (ArrowState (FilterState Double) (-&gt;))<br>    In the expression: applyFilter convT s [1, 0, 0, 0, ....]<br>    In the definition of `it&#39;: it = applyFilter convT s [1, 0, 0, ....]</p></blockquote>
<p>I thought, &quot;maybe, I need to derive from <em>ArrowState</em> in my <em>Filter</em> type definition.&quot;<br>So, I tried making this change to the code:</p>
<p><font face="courier new,monospace">28 newtype Filter b c = F {<br>29     runFilter :: (b, FilterState b) -&gt; (c, FilterState b)<br>30   } deriving (ArrowState (FilterState x))</font></p>
<p>but then I was back to no compile:</p>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">
<p>Filter.hs:30:14:<br>    Can&#39;t make a derived instance of<br>      `ArrowState (FilterState x) Filter&#39;<br>      (even with cunning newtype deriving):<br>      cannot eta-reduce the representation type enough<br>
    In the newtype declaration for `Filter&#39;</p></blockquote>
<p>Do you have any advice?</p>
<p>Thanks,<br>-db</p>
<p> </p>