<p dir="ltr">Hey Victor,</p>
<p dir="ltr">If you're not actually the Monad instance of IO,<br>
then `andThen` is (*>) for `Compose RowParser IO a` (<a href="https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Functor-Compose.html">https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Functor-Compose.html</a>).</p>
<p dir="ltr">So `rowPrinter` would be</p>
<p dir="ltr">rowPrinter =<br>
  getCompose $<br>
  Compose (printP1 <$> field) *><br>
  Compose (printP2 <$> field) *><br>
  ...<br>
  Compose (printPn <$> field)</p>
<p dir="ltr">It's a bit more verbose, but I think it's the best answer.</p>
<br><div class="gmail_quote"><div dir="ltr">On Thu, 28 Sep. 2017, 6:54 pm Viktor Dukhovni, <<a href="mailto:ietf-dane@dukhovni.org">ietf-dane@dukhovni.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
When generating a report file from a database I found it much more<br>
efficient (significantly shorter runtime) to represent each row<br>
by an I/O action that prints the row, rather than to construct a<br>
Row object that to print and throw away.<br>
<br>
But the naive way to construct the I/O action can be tedious to<br>
maintain once the column count gets appreciably high:<br>
<br>
    newtype Foo = Foo { _foo :: IO () }<br>
    instance FromRow Foo where<br>
      fromRow = Foo <$> (rowPrinter <$> field <*> field <*> field <*> ... <*> field)<br>
        where<br>
          rowPrinter :: Type1 -> Type2 -> Type3 -> ... -> TypeN -> IO ()<br>
          rowPrinter p1 p2 p3 ... pN = do<br>
            printP1<br>
            printP2<br>
            printP3<br>
            ...<br>
            printPN<br>
<br>
So I decided to applicatively decompose the rowPrinter function<br>
(with the actual name of "andthen" to be determined later) as:<br>
<br>
   rowPrinter = (printP1 <$> field) `andthen`<br>
                (printP2 <$> field) `andthen`<br>
                (printP3 <$> field) `andthen`<br>
                ...<br>
                (printPN <$> field)<br>
<br>
which avoids the need to package the column printers explicitly into<br>
a single function, and may be somewhat more efficient a well.<br>
<br>
What was not immediately obvious to me was whether there's an "off the<br>
shelf" implementation of "andthen" I could just reuse. The necessary<br>
operator satisfies:<br>
<br>
        andthen (f (m a)) (f (m b)) = f (ma >> mb)<br>
<br>
or, equivalently:<br>
<br>
        a `andthen` b = (>>) <$> a <*> b<br>
<br>
for which <a href="http://pointree.io" rel="noreferrer" target="_blank">http://pointree.io</a> dutifully gives me:<br>
<br>
       andthen = (<*>) . ((>>) <$>)<br>
<br>
Its type signature is:<br>
<br>
    Prelude> :set prompt "l> "<br>
    l> :m + Control.Applicative<br>
    l> :m + Control.Monad<br>
    l> :t ((<*>) . ((>>) <$>))<br>
    ((<*>) . ((>>) <$>))<br>
      :: (Monad m, Applicative f) => f (m a) -> f (m b) -> f (m b)<br>
    l><br>
<br>
It seems to me that this would have been done before, and the operator<br>
would already be present in some package, but I'm having trouble finding<br>
it.<br>
<br>
(Due to the hidden constructors of FromRow defining a Semigroup does not<br>
 work out here, so I can't use (<>), which also inconveniently conflicts<br>
 with  Monoid (<>)).<br>
<br>
So my question is whether the operator in question is already available,<br>
under some name in some package, or else suggested names for it if new.<br>
<br>
--<br>
        Viktor.<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div>