Fredrik
Fredrik

Reputation: 4171

Equivalent of a traverse in arrow notation

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

Answers (1)

Alec
Alec

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.

EDIT

If there is an Arrow equivalent, Traversing may be a generalizing abstraction.

Upvotes: 5

Related Questions