如何以自然顺序高效地构建erlang列表?

如何以自然顺序高效地构建erlang列表?,erlang,Erlang,在本书中,有一些示例伪代码显示了有效地将元素添加到列表头的模式: some_function([H|T], ..., Result, ...) -> H1 = ... H ..., some_function(T, ..., [H1|Result], ...); some_function([H|T], ..., Result, ...) -> {..., Result, ...}. 我仍然习惯于函数式编程,所以上面的例子对我来说有点太抽象了,我现在无法理解

在本书中,有一些示例伪代码显示了有效地将元素添加到列表头的模式:

some_function([H|T], ..., Result, ...) ->
    H1 = ... H ...,
    some_function(T, ..., [H1|Result], ...);
some_function([H|T], ..., Result, ...) ->
    {..., Result, ...}.
我仍然习惯于函数式编程,所以上面的例子对我来说有点太抽象了,我现在无法理解

我认为如果有一个我可以剖析的模式的具体实现,就更容易理解了


问题:是否有人可以提供此模式的简单具体实现

假设我们需要一个类似于
uniq
命令的函数。 该函数获取元素列表,并返回一个列表,其中包含一个元素的所有连续出现项,该元素的一次出现项替换了该元素的所有连续出现项。 下面介绍了一种可能的方法:

uniq(L) ->
    uniq(L, []).

uniq([], Acc) ->
    lists:reverse(Acc);
uniq([H, H | T], Acc) ->
    uniq([H | T], Acc);
uniq([H | T], Acc) ->
    uniq(T, [H | Acc]).
通过在
Acc
列表(最便宜的插入成本)的开头插入新元素,我们建立了一个累加器,一旦我们完成了,我们就反转整个列表以获得元素的初始顺序


我们两次“访问”初始列表中的某些元素,但总成本仍然是线性的,即仅取决于初始列表中元素的数量。

假设我们需要一个类似于
uniq
命令的函数。 该函数获取元素列表,并返回一个列表,其中包含一个元素的所有连续出现项,该元素的一次出现项替换了该元素的所有连续出现项。 下面介绍了一种可能的方法:

uniq(L) ->
    uniq(L, []).

uniq([], Acc) ->
    lists:reverse(Acc);
uniq([H, H | T], Acc) ->
    uniq([H | T], Acc);
uniq([H | T], Acc) ->
    uniq(T, [H | Acc]).
通过在
Acc
列表(最便宜的插入成本)的开头插入新元素,我们建立了一个累加器,一旦我们完成了,我们就反转整个列表以获得元素的初始顺序


我们两次“访问”初始列表中的某些元素,但总成本仍然是线性的,即仅取决于初始列表中元素的数量。

以下是我让您的模式执行的唯一方法:

some_func([H|T], 4, Result, 4) -> 
    H1 = H * 2,
    some_func(T, 3, [H1|Result], 4); 
some_func([H|T], 3, Result, _) ->
    {H, Result, T}.

--output:--

25> a:some_func([1, 2, 3], 4, [], 4).  
{2,[2],[3]}
…这没什么用

伪代码中的模式对我来说毫无意义,所以我将加入你的困惑

下面是另一种尝试:

some_func([H|T], [_|T2], Result, Y) -> 
    H1 = H * Y,
    some_func(T, T2, [H1|Result], Y); 
some_func([H|T], [], Result, _) ->
    {H, Result, T}.


--output:--
34> a:some_func([1, 2, 3, 4], [one, two, three], [], 2).
{4,[6,4,2],[]}

以下是我可以让您的模式执行的唯一方法:

some_func([H|T], 4, Result, 4) -> 
    H1 = H * 2,
    some_func(T, 3, [H1|Result], 4); 
some_func([H|T], 3, Result, _) ->
    {H, Result, T}.

--output:--

25> a:some_func([1, 2, 3], 4, [], 4).  
{2,[2],[3]}
…这没什么用

伪代码中的模式对我来说毫无意义,所以我将加入你的困惑

下面是另一种尝试:

some_func([H|T], [_|T2], Result, Y) -> 
    H1 = H * Y,
    some_func(T, T2, [H1|Result], Y); 
some_func([H|T], [], Result, _) ->
    {H, Result, T}.


--output:--
34> a:some_func([1, 2, 3, 4], [one, two, three], [], 2).
{4,[6,4,2],[]}

这需要一个分解列表,即

[[],[2],[3],[2,2],[5],[2,3],[7],[2,2,2],etc...]
移除所有的素数

remove_primes([HD|TL], Results) -> 

    case length(HD) of
           0 -> % You're at 1
                  remove_primes (TL , Results);
           1 -> % Its a prime, remove it, and keep going
                  remove_primes( TL , Results) ;
           _ -> % its not prime, leave it in and keep going.  
                  remove_primes(TL, [ HD | Results]) 
    end;

remove_primes([], Result) -> 
                 {Result}.
Joe Armstrong所指的结构也是遍历列表并将函数应用于列表中每个元素的标准结构。在本例中,我希望根据每个元素的内容对其进行不同的处理

在实践中,使用映射、过滤器等更容易,因此我相信您将更经常地看到这些,但正如您似乎知道的,理解基础知识对于成为一名熟练的函数式程序员至关重要

为了集中与“按自然顺序构建列表”相关的信息,是否有人知道为什么在函数级别进行模式匹配是有效的,而“解包”变量则不行?(比较一下)(它不起作用)

删除素数(分解的素数列表,结果)->
[HD | TL]=分解的列表,%unpack列表%1
移除_素数(TL,结果);
1->%这是一个素数,删除它,然后继续
移除_素数(TL,结果);
_->%它不是素数,保留它并继续。
移除素数(TL,[HD |结果])
结束;
删除_素数([],结果)->
{Result}。
我相信这会导致更可读的代码,但它似乎不起作用


-rC

这需要一个分解列表,即

[[],[2],[3],[2,2],[5],[2,3],[7],[2,2,2],etc...]
移除所有的素数

remove_primes([HD|TL], Results) -> 

    case length(HD) of
           0 -> % You're at 1
                  remove_primes (TL , Results);
           1 -> % Its a prime, remove it, and keep going
                  remove_primes( TL , Results) ;
           _ -> % its not prime, leave it in and keep going.  
                  remove_primes(TL, [ HD | Results]) 
    end;

remove_primes([], Result) -> 
                 {Result}.
Joe Armstrong所指的结构也是遍历列表并将函数应用于列表中每个元素的标准结构。在本例中,我希望根据每个元素的内容对其进行不同的处理

在实践中,使用映射、过滤器等更容易,因此我相信您将更经常地看到这些,但正如您似乎知道的,理解基础知识对于成为一名熟练的函数式程序员至关重要

为了集中与“按自然顺序构建列表”相关的信息,是否有人知道为什么在函数级别进行模式匹配是有效的,而“解包”变量则不行?(比较一下)(它不起作用)

删除素数(分解的素数列表,结果)->
[HD | TL]=分解的列表,%unpack列表%1
移除_素数(TL,结果);
1->%这是一个素数,删除它,然后继续
移除_素数(TL,结果);
_->%它不是素数,保留它并继续。
移除素数(TL,[HD |结果])
结束;
删除_素数([],结果)->
{Result}。
我相信这会导致更可读的代码,但它似乎不起作用


-rC

你能得到实际的模式来做一些有用的事情吗?如果第二条在上面,那就容易多了。你能得到实际的模式来做一些有用的事情吗?如果第二个子句在上面,那就容易多了。你能给出一个关于伪代码应该做什么的精确引用吗?你确定这就是伪代码吗?我本来想买那本书,但现在我有点怀疑了。@7stud-我不会仅凭这一个例子来判断这本书。总的来说,这本书真的很好。你能给出一个关于伪代码应该做什么的精确引用吗?你确定这就是伪代码吗?我本来想买那本书,但现在我有点怀疑了。@7stud-我不会仅凭这一个例子来判断这本书。总的来说,这本书真的很好。