<div dir="ltr">The paper &quot;Programming with Arrows&quot; of John Hughes gives some exercises to do [1].<div>I&#39;m trying to solve it and would like to receive a feedback if I&#39;m doing it right or not before reading the rest of the paper.</div>

<div>I didn&#39;t find the answers in the internet (if someone could point me to it, please do so).</div><div><br></div><div>Exercise 2 (section 2.5) is asking to create a Stream Processor that can map more than one output per input (e.g. 3 outcomes for a single consume of the stream).</div>

<div><br></div><div>The paper says that implementing &quot;first&quot; will be tricky, and it really is. I&#39;ve came up to the solution listed below, <b>is it right?</b></div><div><b><br></b></div><div><b><br></b></div>

<div><div><font face="courier new, monospace">module SP where</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">import Prelude hiding (id, (.))</font></div><div>

<font face="courier new, monospace">import Control.Category</font></div><div><font face="courier new, monospace">import Control.Arrow</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">data SP a b = Put b (SP a b) | Get (a -&gt; SP a b)</font></div>

<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">runSP :: SP a b -&gt; [a] -&gt; [b]</font></div><div><font face="courier new, monospace">runSP (Put b s) as = b:runSP s as</font></div>

<div><font face="courier new, monospace">runSP (Get k) (a:as) = runSP (k a) as</font></div><div><font face="courier new, monospace">runSP (Get k) [] = []</font></div><div><font face="courier new, monospace"><br></font></div>

<div><font face="courier new, monospace">compose :: SP b c -&gt; SP a b -&gt; SP a c</font></div><div><font face="courier new, monospace">compose (Put a s) g = Put a (compose s g)</font></div><div><font face="courier new, monospace">compose (Get k) (Put a s) = compose (k a) s</font></div>

<div><font face="courier new, monospace">compose f (Get k) = Get (\a -&gt; compose f (k a))</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">instance Category SP where</font></div>

<div><font face="courier new, monospace">  id = arr id</font></div><div><font face="courier new, monospace">  (.) = compose</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">instance Arrow SP where</font></div>

<div><font face="courier new, monospace">  arr f = Get (\a -&gt; Put (f a) (arr f))</font></div><div><font face="courier new, monospace">  first (Put a s) = Get (\(a&#39;, c) -&gt; Put (a, c) (delayed (a&#39;, c) s))</font></div>

<div><font face="courier new, monospace">  first (Get k) = Get (\(a, c) -&gt; firstWithValue (k a) c)</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">delayed :: (a, c) -&gt; SP a b -&gt; SP (a, c) (b, c)</font></div>

<div><font face="courier new, monospace">delayed (a, c) (Put b s) = Put (b, c) (delayed (a, c) s)</font></div><div><font face="courier new, monospace">delayed (a, c) (Get k) = firstWithValue (k a) c</font></div><div><font face="courier new, monospace"><br>

</font></div><div><font face="courier new, monospace">firstWithValue :: SP a b -&gt; c -&gt; SP (a, c) (b, c)</font></div><div><font face="courier new, monospace">firstWithValue (Put a s) c = Put (a, c) (firstWithValue s c)</font></div>

<div><font face="courier new, monospace">firstWithValue (Get k) _ = Get (\(a, c) -&gt; firstWithValue (k a) c)</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">input :: [(String, String)]</font></div>

<div><font face="courier new, monospace">input = [(&quot;a1&quot;, &quot;a2&quot;), (&quot;b1&quot;, &quot;b2&quot;), (&quot;c1&quot;, &quot;c2&quot;), (&quot;d1&quot;, &quot;d2&quot;)]</font></div><div><font face="courier new, monospace"><br>

</font></div><div><font face="courier new, monospace">myArrow :: SP (String, String) (String, String)</font></div><div><font face="courier new, monospace">myArrow = (delay &quot;db1&quot; &gt;&gt;&gt; delay &quot;da1&quot;) *** (delay &quot;db2&quot; &gt;&gt;&gt; delay &quot;da2&quot;)</font></div>

<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">delay :: a -&gt; SP a a</font></div><div><font face="courier new, monospace">delay b = Put b (arr id)</font></div><div><font face="courier new, monospace"><br>

</font></div><div><font face="courier new, monospace">main :: IO ()</font></div><div><font face="courier new, monospace">main = let output = runSP myArrow input in mapM_ f output</font></div><div><font face="courier new, monospace">  where f (a, b) = putStrLn $ &quot;(&quot; ++ show a ++ &quot;, &quot; ++ show b ++ &quot;)&quot;</font></div>

</div><div><b><br></b></div><div><br></div><div>The output of &quot;main&quot; is:</div><div><br></div><div><br></div><div><div><font face="courier new, monospace">*SP&gt; main</font></div><div><font face="courier new, monospace">(&quot;da1&quot;, &quot;da2&quot;)</font></div>

<div><font face="courier new, monospace">(&quot;da1&quot;, &quot;db2&quot;)</font></div><div><font face="courier new, monospace">(&quot;da1&quot;, &quot;a2&quot;)</font></div><div><font face="courier new, monospace">(&quot;db1&quot;, &quot;a2&quot;)</font></div>

<div><font face="courier new, monospace">(&quot;a1&quot;, &quot;a2&quot;)</font></div><div><font face="courier new, monospace">(&quot;b1&quot;, &quot;b2&quot;)</font></div><div><font face="courier new, monospace">(&quot;c1&quot;, &quot;c2&quot;)</font></div>

<div><font face="courier new, monospace">(&quot;d1&quot;, &quot;d2&quot;)</font></div></div><div><br></div><div><br></div><div>[1] <a href="http://www.cse.chalmers.se/~rjmh/afp-arrows.pdf">http://www.cse.chalmers.se/~rjmh/afp-arrows.pdf</a><br>

</div></div>