【问题标题】:Problems understanding sequential Erlang理解顺序 Erlang 的问题
【发布时间】:2014-02-03 07:30:08
【问题描述】:

我一直在检查一个代码示例,但我无法理解发生了什么,我试图理解更简单的示例并获得它们,但在这个我遇到了困难:

seq([X, X | Xs]) -> [X | seq(Xs)];
seq([X, Y | Xs]) -> [X, Y | seq(Xs)];
seq(_) -> [].

当我在 shell 中使用 [1,1,1,2,2,2,3] 运行它时,我得到 [1,1,2,2]。我一直试图通过写在纸上来理解这些步骤,但我被卡在了一半的低谷。

我将不胜感激所有向我解释此处发生的步骤的答案! :) /埃里。

【问题讨论】:

  • 我假设你想得到 [1,2,3] 作为输出?请说明预期结果。
  • 我不想得到任何具体的输出,我只是想了解顺序 erlang 是如何工作的,我上面提供的代码就是一个例子。当我用 [1,1,1,2,2,2,3] 运行它时,我得到 [1,1,2,2],我只想知道它是如何得到 [1,1,2,2] ] 以了解如何执行这些步骤。因此,我希望有人向我解释这些步骤。

标签: erlang


【解决方案1】:

好的,所以我们从[1,1,1,2,2,2,3] 的列表开始。

在第一次调用seq 时,erlang 会将前两个元素11 匹配到seq - seq([X, X | Xs]) 的第一个“子句”。 这将初始化将成为最终返回值[1, seq(Xs)] 的列表。现在此时Xs 将绑定到值[1,2,2,2,3]。如果您想知道为什么 Xs 列表的开头没有两个 1,那是因为我们在 [X, X | Xs] 上匹配/绑定了其中两个。

返回值 = [1 | ?](? 是要计算的剩余递归)
Xs = [1,2,2,2,3]

在第二次调用seq 时,erlang 会将输入列表12 的前两个元素匹配到第二个子句seq([X, Y | Xs])。然后我们从这次运行中“返回”列表 [X, Y] 或 [1, 2],并使用 Xs = [2,2,3] 调用下一次迭代。

返回值 = [1 | [1, 2 | ?]] Xs = [2,2,3]

在第三次调用时,前两个元素再次相同,因此 erlang 再次运行第一个子句。 seq([X, X | Xs]) -> [X | seq(Xs)]。我们返回单个 2 值作为评估的一部分,然后调用 seq([3])

返回值 = [1 | [1, 2 | [2 | ?]]]
Xs = [3]

最后,最后一个案例。我们的 [3] 列表不匹配 [X, X | Xs] 也不匹配 [X, Y, Xs],所以 erlang 将运行我们的全部:seq(_) -> []. _ 将匹配任何内容,并且不将值绑定到任何局部变量,所以我们所有在这里做的是返回一个空列表[]

那么我们的最终返回值为:[1 | [1, 2 | [2 | []]]]。如果您将其评估为您的 erl repl,您会看到它与列表 [1,1,2,2] 相同,后者是前者的语法糖。

【讨论】:

  • 非常感谢!!你解释得很好,我现在明白了,太棒了!!!
【解决方案2】:

追踪可以帮助你一点:

1> dbg:tracer().
{ok,<0.35.0>}
2> dbg:p(self(), [c]).
{ok,[{matched,nonode@nohost,1}]}
3> dbg:tpl({test, seq, 1}, [{'_',[],[{return_trace}]}]).
{ok,[{matched,nonode@nohost,1},{saved,1}]}
4> test:seq([1, 1, 1, 2, 2, 2, 3]).
(<0.33.0>) call test:seq([1,1,1,2,2,2,3])
(<0.33.0>) call test:seq([1,2,2,2,3])
(<0.33.0>) call test:seq([2,2,3])
(<0.33.0>) call test:seq([3])
(<0.33.0>) returned from test:seq/1 -> []
(<0.33.0>) returned from test:seq/1 -> [2]
(<0.33.0>) returned from test:seq/1 -> [1,2,2]
(<0.33.0>) returned from test:seq/1 -> [1,1,2,2]
[1,1,2,2]

【讨论】:

  • 如果函数是尾递归的,它会更有帮助,因为生成的值也会在跟踪中可见。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-29
  • 2013-01-06
  • 2015-09-03
  • 2020-03-06
  • 2019-10-12
  • 2020-08-08
  • 2016-01-15
相关资源
最近更新 更多