10

我已经阅读了箭头符号文档页面,但我并不完全清楚在“7.10.3.Defining your own control structure”下使用的“管道括号”是什么。

鉴于上述文档中的示例

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

不使用箭头符号的等效代码是什么?

4

2 回答 2

15

括号(通常称为香蕉括号)用于在proc表示法中应用对命令进行操作的(| ... |)函数。它们用于区分对命令(称为“运算符”)进行操作的功能与普通命令。二进制中缀运算符是特殊情况,因此您无需编写.(| (&&&) x y |)

至于脱糖,它们是来自Arrows 论文的 GHC 版本的form关键字。

形式定义如下:

proc p -> form 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)
于 2012-01-15T11:41:30.393 回答
1

这是一个非常粗略和直观的答案,我不确定它是否正确,但感觉确实如此。如果你有

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

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

then(| |)是将作用域中的所有<--bound 变量输入到blocks 中的一种方式,即它变成(等效于)

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)

我只是在阅读 Oliver Charles 的Rel8 中的 antijoins文档时才明白这一点。我仍然觉得它相当令人费解。

于 2018-02-25T09:34:41.790 回答