Your type stopped being an arrow when the state type started to depend on the input type:<br><br>Filter a b ~= (a, FS a) -&gt; (b, FS a)<br><br>Filter b c ~= (b, FS b) -&gt; (c, FS b)<br><br>It&#39;s impossible to compose these two functions into a single function of type Filter a c, because the state type doesn&#39;t match.<br>
<br>You need to make the filter state not dependent on the input type:<br><br>newtype Filter s a b = F { runFilter :: (a, FilterState s) -&gt; (b, FilterState s) }<br><br>You can still create objects with the type<br>   Filter a a b<br>
which correspond to your old filter type.  But these functions will always &#39;start&#39; a pipeline.  Which I think is what you want anyways!<br><br>  -- ryan<br><br><br><div class="gmail_quote">On Tue, Oct 18, 2011 at 2:35 PM, Captain Freako <span dir="ltr">&lt;<a href="mailto:capn.freako@gmail.com">capn.freako@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><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" target="_blank">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" target="_blank">haskell-cafe@haskell.org</a><br>Message-ID: &lt;BLU0- <br><a href="mailto:SMTP384394452FD2750FBE3BCFCC6E50@phx.gbl" target="_blank">SMTP384394452FD2750FBE3BCFCC6E50@phx.gbl</a>&gt;<br>
Content-Type: text/plain; charset=&quot;ISO-8859-1&quot;; format=flowed</div><div class="im">

<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></div></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 :: <b>(ArrowState (FilterState b) (-&gt;)) =&gt;</b> 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 <i>ArrowState</i> in my <i>Filter</i> 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>
<br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br></blockquote></div><br>