有没有更好的方法来写 Head and Tail 而不用 fun?

Is there a better way to write Head and Tail without using fun?

f6(List) ->
     
          [Head2 | Tail2 ] <- [List],
          Head2.
          Tail2.

你好,我一直在想办法在不使用 fun 的情况下使用 Head 和 Tail,对于 shell 我们可以将 head 和 tail 分配为 [H|T] = A。但是对于编辑器,我完全不知道,因为我只是在学习。任何帮助将不胜感激。 我只需要知道在带有 H & T 的列表中添加数字是多么简单。

示例输入:[1,2,3] 或任意三个数字,输出将类似于总数 6。我被困在只能将列表分配给头部和尾部的位置。

如有错误格式请见谅,在此先感谢。

几个紧迫的问题:

<- 用于列表理解。参见 https://www.erlang.org/doc/programming_examples/list_comprehensions.html or https://learnyousomeerlang.com/starting-out-for-real#list-comprehensions

分配(实际上是匹配)在模块中的工作方式相同:

    [H | T] = L,
    % ...do something with H and T...

下一个:

[Head2 | Tail2 ] <- [List],

这也不是您想要的,即使我们修复了 <-。您已将您的列表包装在另一个列表中,因此如果您以 List = [1, 2, 3] 开始,您实际上会做 [Head2 | Tail2] = [[1, 2, 3]],并且您将以 Head2 = [1, 2, 3]Tail2 = [] 结束].


在 shell 之外,你 必须 将你的 Erlang 代码放在一个模块中,所以你最终会得到这样的东西(模块名称必须与文件名,所以 my_module.erl):

-module(my_module).

% ...

在您的示例代码中,我已经纠正了上述两个问题,这给我们留下了:

f6(List) ->
          [Head2 | Tail2 ] = List,
          Head2.
          Tail2.

这仍然行不通,因为点 (.) 表示函数结束。所以 Tail2. 只是闲逛,导致语法错误。

如果要对列表中的三个数字求和,最简单的选择是:

-module(my_module).

f6([A, B, C]) ->
   A + B + C.

这在函数头中使用了匹配。它 需要 一个 three-element 列表,并且它匹配它使得 A、B 和 C 中的每一个都取其中一个元素。然后您可以添加它们。

不是很灵活。您可能想要的是递归:

% don't do this, though; read on.
sum([H | T]) ->
    H + sum(T);
sum([]) ->
    0.

但是 这会破坏堆栈,因为它不是 tail-recursive。你实际上想要的是:

sum(List) ->
    sum(List, 0).

sum([], Acc) ->
    Result;
sum([Elt | Rest], Acc) ->
    sum(Rest, Acc + Elt).

这使用带有 tail-recursion 的累加器来添加列表中的值。

这可能是 re-written 如下(直接取自 https://www.erlang.org/doc/man/lists.html#foldl-3 的文档:

sum(List) -> lists:foldl(fun(X, Sum) -> X + Sum end, 0, List).

但是,如果您真的想要短版,那么已经有lists:sum(List)了。参见 https://www.erlang.org/doc/man/lists.html#sum-1

I have been trying to figure out the way to use Head and Tail without using fun and for the shell we can just assign the head and tail as [H|T] = A. But for the editor I have absolutely no idea...

在shell:

~/erlang_programs$ erl
Erlang/OTP 24 [erts-12.0.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]

Eshell V12.0.2  (abort with ^G)
1> List = [dog, 20, 30].
[dog,20,30]

2> [H|T] = List.
[dog,20,30]
3> io:format("Head = ~w~n", [H]).
Head = dog
ok

4> io:format("Tail = ~w~n", [T]).
Tail = [20,30]
ok

这是一个想法:

-module(a).
-export([f1/1]).

f1(List) ->   %% or you could write it as f([H|T]) -> 
    [H|T] = List,
    io:format("Head = ~w~n", [H]),
    io:format("Tail = ~w~n", [T]).

使用shell中的模块:

~/erlang_programs$ erl
Erlang/OTP 24 [erts-12.0.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]

Eshell V12.0.2  (abort with ^G)

1> c(a).
{ok,a}

2> List = [dog, 20, 30].
[dog,20,30]

3> a:f1(List).
Head = dog
Tail = [20,30]
ok

几乎相同。

I just need to know how a simple adding the number in a list with H & T looks like.

这是您需要的技巧:

-module(a).
-export([sum_it/1]).

sum_it(List) ->
    StartTotal = 0,
    sum_it(List, StartTotal).

sum_it([H|T], Total) -> 
    CurrentTotal = Total + H,
    sum_it(T, CurrentTotal);
sum_it([], Total) ->
    Total.

您定义了一个函数 sum_it/1,它只接受参数,然后调用另一个函数来完成工作:sum_it/2。定义第二个函数,它可以具有相同的名称(因为它具有不同数量的参数)或不同的名称,允许您为累加器传递一个额外的参数。因为erlang没有全局变量存放结果,所以可以在函数参数变量中加一个累加器变量存放结果。

sum_it/2 函数定义的情况下,您有函数参数变量 [H|T] 来匹配一个列表,其中包含您要求和的数字,然后添加累加器变量 Total 存储结果。