Reputation: 4171
I'm using the hasql library to interact with a PostgreSQL database and it uses Arrows for queries and query composition.
I have a simple query with this type:
setCustomerAttributes :: Query (TagData, UserDetails) ()
where Query
is the arrow (TagData, UserDetails)
is the input and it returns ()
.
Now I want to write a query that takes several TagData
as input and just runs this query for all of them.
Essentially I'd want to do something like this
setManyCustomerAttributes :: Query ([TagPair], Customer) ()
setManyCustomerAttributes = proc (pairs, customer) -> do
returnA -< traverse_ (\pair -> setCustomerAttribute -< (pair, customer)) pairs
However this of course produces the error Arrow command found where expression was expected
, as you can't just mix and match arrow notation and regular expressions like that.
What is the arrow equivalent of doing a traverse like that?
Upvotes: 3
Views: 182
Reputation: 32319
You need something stronger than just Arrow
- you'll need ArrowChoice
. Thankfully, Query
is an instance of that too. You can make something work with
setManyCustomerAttributes :: Query ([TagData], UserDetails) ()
setManyCustomerAttributes = proc (pairs,customer) ->
case pairs of
[] -> returnA -< ()
(p:ps) -> do
setCustomerAttributes -< (p,customer)
setManyCustomerAttributes -< (ps,customer)
I'm still thinking about if there is some interesting abstraction analogous to traverse
worth generalizing here.
If there is an Arrow
equivalent, Traversing
may be a generalizing abstraction.
Upvotes: 5