我有一个关于Erlang Perms实现的问题:
perms([]) -> [[]]; perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].
上面的代码来自一本名为Erlang Programming的书,它看起来非常简单但运行完美.我困惑的是它是如何工作的.例如,让我们用一个参数运行它perms("12")
,然后如果我们分析递归的过程.我认为第一次回归的结果将是,[[1|perms[2]->[[2]|[[]]]]
并且这等于[[1|[[2]|[[]]]]
.但它在Erlang shell中是一个错误的表达.
列表推导的一般行为是生成所有生成器的叉积(在应用定义的过滤器之后).通过一个例子更好地说明:
1> [{X,Y} || X <- [1,2,3], Y <- [a,b,c]]. [{1,a},{1,b},{1,c},{2,a},{2,b},{2,c},{3,a},{3,b},{3,c}] 2>
在排列代码示例中,列表推导以这种方式执行:
H <- L
为发电机,它会产生一个值在您的情况下,输入列表L中的每个术语,L ="12"时,它会产生2个方面的字符$1
和$2
,并且将建立的叉积与第二的结果发电机:T <- perms(L--[H])
这里有一些非常聪明的东西,第二个发电机依赖于第一个发电机,第一个发电机的每个元件将与第二个发电机的自己的列表相结合.因此$1
将与perms(L--[$1])
= 生成的术语组合perms("2")
如果您尝试评估perms("2")
,则相同的分析显示第一个生成器生成一个单独的术语$2
以进行组合perms([])
评估为的最后一个术语[[]]
将生成一个空列表.
我们现在可以建立中间结果:[[H|T]] = [[$2|[]]] = [[$2]]
.
该结果将生成单个术语[$2]
.因此,最高级别的结果将是(考虑所有生成的术语) [[$1|[$2]],[$2|[$1]] = [[$1,$2],[$2,$1]] = ["12","21"]
.