В чем заключаются специальные скобки (|... |)?

Я прочитал страницу документации по нотам стрелок, но мне не совсем понятно, что такое "скобки труб", используемые в разделе "7.10. 3. Определение собственных структур управления" desugar".

Учитывая пример в приведенном выше документе

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

Что эквивалентный код без использования обозначений стрелок?

Ответ 1

Скобки (| ... |) (обычно называемые скобками бананов) предназначены для применения функции, которая работает с командами, внутри proc. Они используются для устранения неоднозначности функции, которая управляет командами (называемыми "оператором" ) из обычной команды. Бинарные инфиксные операторы имеют специальную оболочку, поэтому вам не нужно писать (| (&&&) x y |).

Что касается desugaring, это версия GHC ключевого слова формы из статьи со стрелками.

Форма

определяется следующим образом:

proc p → форма e c1 c2... cn

=

e ( proc p → c1) ( proc p → c2)... ( proc p → cn)

Итак, proc x -> (|untilA (increment -< x+y) (within 0.5 -< x)|) станет:

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

Если вы хотите полностью удалить его, так что синтаксис стрелки не останется, это будет:

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

Ответ 2

Это очень грубый и интуитивный ответ, и я не уверен, что это правильно, но похоже, что это так. Если у вас есть

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

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

тогда (| |) является способом подачи во все <- -переменные переменные в области видимости в block s, т.е. становится (эквивалентным)

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)

Я понял это только при чтении документов Оливера Карла для > антиоинов в Rel8. Я все еще нахожу это скорее умопомрачительным.