需要帮助理解这个erlang代码

时间:2009-10-15 03:11:15

标签: functional-programming erlang

我无法理解这一行。

[Pid2 ! {delete, V1a}
    || {Pid1a, V1a} <- PV1a, Pid2 <- P2, Pid1a /= Pid2
  ],

以下是我的理解:   双管“||”之前的任何东西根据双管后面的内容重复完成。所以带有删除原子的消息会重复发送到Pid2。 我知道'/ ='意味着不平等。我不明白'&lt; - '是什么意思,最终意味着整行意味着什么。

3 个答案:

答案 0 :(得分:15)

[something(X) || X <- L],是列表理解。 L是一个元素列表,这个表达式创建了一个新元素列表,通过在其上调用something()来形成每个元素。

[something(X,Y) || X <-L, Y<-M]类似,但是为X和Y中每个元素的笛卡尔积创建了一个元素。

[something(X) || X <-L, Expr]是一个过滤表达式。与第一个相同,但它仅对L的元素执行,其中Expr对于给定的X为真。

[something(X) || {X,..} <-L, Expr]是另一种过滤器。在列表理解中,只有那些元素可以被元素匹配。

还有一件事需要知道,这不仅可以用于生成另一个列表,还可以用于为每个元素执行命令。如果列表推导的结果不匹配,编译器将知道根本不生成列表。此行为可用于模仿其他语言的foreach

一些例子:

1> [ X*2 || X <- [1,2,3] ].
[2,4,6]
2> [ X*Y || X <- [1,2], Y <- [3,4,5] ].
[3,4,5,6,8,10]
3> [ X*3 || X <- [1,2,3,4], X rem 2 == 0 ].
[6,12]
4> [ X || {a,X} <- [{a,1},{a,2},{b,3},{c,4}] ].
[1,2]

因此,您的代码生成来自PV1a的所有{Pid1a,V1a}元素和来自P2的Pid2元素的笛卡尔积,除了那些Pid1a等于Pid2的元素,并且对于这些元素中的每一个都发送{delete,V1a}消息PID2。

答案 1 :(得分:5)

我不知道Erlang,但这看起来就像我知道的一堆语言中的列表推导。希望这个猜测会帮助你,直到有人知道Erlang可以回答:

[Pid2 ! {delete, V1a} || {Pid1a, V1a} <- PV1a, Pid2 <- P2, Pid1a /= Pid2],

转换为命令式伪代码:

For each item in PV1a, unpacking item to {Pid1a, V1a}
    For each Pid2 in P2
        If Pid1a /= Pid2
            Pid2 ! {delete, V1a} 

换句话说,对于PV1a和P2中的每个Pid,只要Pid1和Pid2不是同一个Pid,就将消息删除V1a发送到Pid2。

答案 2 :(得分:1)

它是list comprehension,&lt; - 运算符用于生成器。

查看一个更受欢迎的LC简介示例;找到三角形,其中整数边的平方等于整数斜边的平方,但是对于给定的整数范围Ns

Ns = [1,2,3,4,5,6,7,8,9].
[{X,Y,C} || X <- Ns, Y <- Ns, C <- Ns, X*X + Y*Y == C*C].

这为我们提供了以下列表作为输出。

[{3,4,5},{4,3,5}]

这似乎是正确的:

3² + 4² = 5²
9 + 16 = 25
25 = 25

因此,列表理解可以读作每个X,Y和C,使得X取自Ns,Y取自Ns,C取自Ns,X²+Y²等于C²。