haskellarrow-abstraction

Why arrows in input are not useable in arrow commands in a proc block?


During my learning about arrows, I stumble on a point which doesn't get clearer with time:

from John Hughes's paper "Generalizing Monads To Arrows", I have noted that this below (case I) is not possible, because the arrow f in parameter cannot be used inside the local scope of the arrow procedure.

-- case I
proc (f,x) -> returnA <- f -< x     --- here the f is illegal   

If we had another arrow, otherArrow, defined elsewhere, we could do:

-- case II
proc (f,x) -> returnA <- otherArrow -< x

I understand the need for the -< like there is no apply for arrows so as to apply x to its input. So we use -< to achieve this (case II).

But I do not see the reason for the impossibility to use an arrow given in parameter to the proc block. (f in proc (f,x) in the case I).

And my not-understanding collides with a term that is often used: arrow command. Papers insists that it is not equivalent to haskell expressions, and that the Haskell type system is not suited for making arrow commands first-class in the language.

Again I do not see what is the fact/the property that makes it impossible to make it first-class in the Haskell type system. Understanding the reason behind this impossibility seems to be the insight I need.

Given the grammar in Ross Paterson's paper:

exp ::=   ...
        | proc pat -> cmd

cmd ::=   exp -< exp
        | form exp cmd1 ... cmdn 
        | cmd1 op cmd2
        | K pat -> cmd
        | (cmd)

From this grammar I do not grasp the reason for the impossibility.

But from translation rules we have:

proc p -> e1 -< e2 = arr $ \p -> e2 >>> e1 -- if intersect Vars(p) and Vars (e1) is empty 
                   = arr $ \p -> (e1,e2) >>> app -- otherwise

In the first branch, we see that the intersection of variables in p and in e1 should be empty... Is this variable scope-limitation the main trait of an arrow command, I mean the reason behind what makes it not possible to make arrow command first-class in Haskell ?

As I am asking, my mind makes not much difference between an arrow-command and a composition-of-arrows (with operators like >>>, which eventually results in an arrow itself) and a simple arrow.


Solution

  • Indeed the grammar appears to be too weak to point out this issue.

    You've basically discovered exactly what makes “Arrow less powerful than Monad”. (FTR, I dislike this comparison – arrows are an abstraction that comes from a fundamentally different direction than monads, only they happen to be able to support most monad operations if used with a Kleisli category.)

    proc notation is a cheat. It allows you to give names to “variables” which don't necessarily correspond to actual values at all (i.e., to something that could also be bound with a lambda). That's ok as long as you only use those to the right of -<, where the desugarer will know how to translate it to fanout/projection operations. In particular, your caseII desugars as

       proc (f,x) -> returnA <- otherArrow -< x
    ≡  proc   fx -> returnA <- otherArrow -< snd fx
    ≡                 id  <<< otherArrow <<< arr snd
    

    But in caseII, you try to bind a virtual variable f that itself represents an arrow to be used in the chain. That's a problem, because you can't build up the chain that would pipe through this “variable” withour already having it available!