我对 Elixir 和函数式编程整体来说还是个新手。我从超级基本的功能开始,直到我发现一个我在互联网上找不到的问题。 我有以下模块
defmodule Logic do
def is_bigger_then_3(list_int, res) when length(list_int) > 0 do
IO.inspect binding()
[head | tail] = list_int
if head > 3 do
is_bigger_then_3 tail, res ++ [true]
end
unless head > 3 do
is_bigger_then_3 tail, res ++ [false]
end
end
def is_bigger_then_3(list_int, res) when length(list_int) == 0 do
IO.inspect binding()
res
end
end
我正在尝试为每个数字小于或大于 3 的情况列出一个列表。
我的预期结果是例如: [1, 2, 3, 4] 返回 [false, false, false, true] 但由于某种原因,返回值为零。 这就是实际返回的内容
iex(27)> list = [1,2,3,4,5,6,7,8,9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
iex(28)> Logic.is_bigger_then_3 list, []
[list_int: [1, 2, 3, 4, 5, 6, 7, 8, 9], res: []]
[list_int: [2, 3, 4, 5, 6, 7, 8, 9], res: [false]]
[list_int: [3, 4, 5, 6, 7, 8, 9], res: [false, false]]
[list_int: [4, 5, 6, 7, 8, 9], res: [false, false, false]]
[list_int: [5, 6, 7, 8, 9], res: [false, false, false, true]]
[list_int: [6, 7, 8, 9], res: [false, false, false, true, true]]
[list_int: ~c"\a\b\t", res: [false, false, false, true, true, true]]
[list_int: ~c"\b\t", res: [false, false, false, true, true, true, true]]
[list_int: ~c"\t", res: [false, false, false, true, true, true, true, true]]
[list_int: [], res: [false, false, false, true, true, true, true, true, true]]
nil
我完全不知道为什么我的结果为零,我也不知道这是怎么发生的。一个解释会非常友善。
中间结果将被丢弃,除非存储在本地变量中和/或从函数返回。
这是您的功能和我的评论。
defmodule Logic do
# we pattern-match here to ensure the length is > 0
def is_bigger_then_3([head | tail] = list_int, res) do
# calculated and then discarded
if head > 3, do: is_bigger_then_3 tail, res ++ [true]
# calculated and then returned as a function result
unless head > 3, do: is_bigger_then_3 tail, res ++ [false]
end
def is_bigger_then_3([], res) do
IO.inspect binding()
res
end
end
也就是说,您只需丢弃计算值,而不是累积。
与下面的内容一起工作
defmodule Logic do
def is_bigger_then_3([head | tail] = list_int, res) do
is_bigger_then_3 tail, res ++ [head > 3]
end
def is_bigger_then_3([], res), do: res
end
旁注: 在链接列表之前添加而不是附加到它们更惯用,如
[head > 3 | res]
而不是 res ++ [head > 3]
,然后反转列表。当时的性能要好得多,现在的性能仍然要好一些。