6

I was reading this, which said:

Well, the point is that arrow notation forbids some computations that do notation allows. In particular all “arrow actions” must be “statically” known“.

and it explains:

Statically known" means that if we have a couple of rows of arrow notation

> -- y <- action1 -< x

> -- z <- action2 -< y

then the expression action2 cannot depend on x or indeed anything bound on the left hand side of an arrow notation row.

As far as I understand, this restriction is what makes arrows worthwhile.

Now, I was trying to learn Opaleye and I noticed that it uses arrows to combine things together.

Why is Opaleye using arrows? Why are arrows a well suited thing for this job? What is it about databases/queries that make this restriction useful?

  • I'm not sure I agree with the idea that that "restriction" is what makes arrows worthwhile. It's pretty trivial to get around using arrow apply, and there's even nice syntactic sugar to do that: `z <- action2 x -<< y` – jkeuhlen May 09 '18 at 14:25
  • Also, this might be helpful reading if you haven't seen it yet: https://stackoverflow.com/questions/3652054/monads-vs-arrows?rq=1 – jkeuhlen May 09 '18 at 14:26
  • 3
    I think it's fundamentally missing the point to always compare arrows to monads. Arrows are foremostly a generalisation of functions/morphisms, whereas monads layer upon objects. Of course, both concepts are strongly linked in a cartesian closed category, but it's still a quite different conceptual approach. – leftaroundabout May 09 '18 at 14:37
  • @leftaroundabout That's fair. I think because they can both capture effectful actions, there is general confusion on when each is more appropriate of a solution so they get compared to each other a lot. – jkeuhlen May 09 '18 at 16:20

2 Answers2

4

Paramaterized database queries look like arrows:

  • each has an input and an output
  • they compose
  • we want to treat them differently than Haskell functions

Composition (.) (or (<<<)) looks like an SQL subquery. (&&&) looks like an SQL join.

I believe that the "statically known" restriction relates to things you might reasonably be able to translate into SQL. Once you allow fmap / lmap / rmap with arbitrary Haskell functions, that isn't feasible (at least without SQL language extensions and GHC compiler plugins). I haven't worked out the details, though.

I don't know how many of the translations we might manage by hand Opaleye implements.

bergey
  • 3,041
  • 11
  • 17
0

There is a difficulty around variable scope when combining aggregation and monadic bind in query languages. I've never come up with a particularly satisfying explanation but you can see a historical Reddit post of mine and a (fixed) issue with relational-record for some details.

Tom Ellis
  • 9,224
  • 1
  • 29
  • 54