Pregunta

I've read the arrow notation documentation page, but it's not entirely clear to me what the "pipe brackets" used under "7.10.3. Defining your own control structures" desugar into.

Given the example in the above document

proc x -> do
    y <- f -< x+1
    (|untilA (increment -< x+y) (within 0.5 -< x)|)

What's the equivalent code without using arrow notation?

¿Fue útil?

Solución

The (| ... |) brackets (usually called banana brackets) are for applying a function that operates on commands, inside proc notation. They are used to disambiguate a function that operates on commands (called an 'operator') from a normal command. Binary infix operators are special cased, so you don't need to write (| (&&&) x y |).

As for the desugaring, they're GHC's version of the form keyword from the Arrows paper.

form is defined as follows:

proc p -> form e c1 c2 ... cn

=

e (proc p -> c1) (proc p -> c2) ... (proc p -> cn)

So, proc x -> (|untilA (increment -< x+y) (within 0.5 -< x)|) would become:

untilA (proc x -> increment -< x+y) (proc x -> within 0.5 -< x)

If you want to desugar this entirely so there is no arrow syntax left, it would become:

untilA (arr (\x -> x+y) >>> increment) (arr (\x -> x) >>> within 0.5)

Otros consejos

This is a very rough and intuitive answer and I'm not certain it's correct but it feels like it is. If you have

proc a -> do
    a1 <- command1 <- ...
    ...
    an <- commandn <- ...

    (| structure (block1 -< expression1[a, a1, ..., an])
                 ...
                 (blockm -< expressionm[a, a1, ..., an])
    |)

then (| |) is a way of feeding in all the <--bound variables in scope into the blocks, i.e. it becomes (equivalent to)

proc a -> do
    a1 <- command1 <- ...
    ...
    an <- commandn <- ...

    structure (proc (a, a1, ..., an) -> do
                   block1 -< expression1[a, a1, ..., an])
              ...
              (proc (a, a1, ..., an) -> do
                   blockm -< expressionm[a, a1, ..., an])
                       -< (a, a1, ..., an)

I only grasped this when reading Oliver Charles's docs for antijoins in Rel8. I still find it rather mind-bending.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top