The only thing I would add to Daniel's answer is that you can use the `managed` library to simplify the type a little bit to:
query' :: Text -> [SqlValue] -> Managed (Maybe Int, Producer [SqlValue] IO ()) Also, since you aren't using the return value of the `Producer`, you can simplify it even further by using `ListT`: query' :: Text -> [SqlValue] -> Managed (Maybe Int, ListT IO [SqlValue]) It's not clear to me, though, why each read from the database returns a list of `SqlValue`s, though On Fri, Jan 20, 2017 at 7:35 AM, Daniel Díaz <diaz.carr...@gmail.com> wrote: > I would keep the API similar to the io-streams, by passing a function that > consumes a Producer > > query' :: Text -> [SqlValue] -> (Maybe Int -> Producer [SqlValue] -> > IO a) -> IO a > > This makes resource handling easier. It would also let you pass pipes > parsers (which can be easily turned into producer-consuming functions). But > perhaps "parsing" the sequence of tuples of a SQL query doesn't make a lot > of sense. > > Another option would be to forgo pipes and just use Folds from the "foldl" > package. Perhaps monadic Folds over ExceptT that would let you "exit early". > > > On Thursday, January 19, 2017 at 8:11:20 PM UTC+1, Bardur Arantsson wrote: >> >> Hi all, >> >> I'm writing an API for a little database library which has -- until now >> -- used io-streams, and I was wondering how one would design the query >> API. >> >> In particular, I have a function similar to: >> >> query' :: Text -> [SqlValue] -> (Maybe Int -> InputStream [SqlValue] >> -> IO a) -> IO a >> query' sql params callback = do >> ... >> >> (I'm actually really using MonadIO, etc., but that shouldn't matter much >> for the question -- I'll have to use SafeT from pipes-safe to ensure >> proper transaction/connection handling, but I don't think that'll change >> things too much.) >> >> The idea is that the user-provided callback receives a "row count" >> (Maybe Int) and an InputStream where it can read as much as it wants >> (until EOS, obviously). Once the callback terminates, the transaction >> commits and the returned value is returned from query' >> >> My question is: How would this API look in the pipes world? The obvious >> candidate would be something like >> >> query' :: Text -> [SqlValue] -> Producer' [SqlValue] m r >> >> but that precludes the "row count". Another option might be >> >> query' :: Text -> [SqlValue] -> (Maybe Int -> Consumer' [SqlValue] m >> r) -> X >> >> ... but I'm unsure whether that even makes sense and what I'd want X to >> be. Any opinions? >> >> -- > You received this message because you are subscribed to the Google Groups > "Haskell Pipes" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to haskell-pipes+unsubscr...@googlegroups.com. > To post to this group, send email to haskell-pipes@googlegroups.com. > -- You received this message because you are subscribed to the Google Groups "Haskell Pipes" group. To unsubscribe from this group and stop receiving emails from it, send an email to haskell-pipes+unsubscr...@googlegroups.com. To post to this group, send email to haskell-pipes@googlegroups.com.