erlang列表理解问题

erlang list understanding problems

我正在尝试计算一个等式 f(Ys) -> [Y * 2 || Y <- Ys, Y < 4].

当我输入列表 f([5,1,2,6]). 时,我得到的结果是 [2,4],而我认为它应该是 [10, false],这是从 f([5,1,2,6]) -> [5 * 2 || 5 <- [1,2,6], 5 < 4].[=15 派生的=]

任何人都可以告诉我我在哪里做错了,或者可以通过正确的过程了解如何获得正确的结果吗?

在您的输入列表元素中,[5,6] 被丢弃,因为 Y < 4 为假,留下 [1,2].

你的输出被评估为 Y * 2 所以 [2,4] 的结果对我有用。

列表理解采用 Ys 的每个值并丢弃谓词不正确的那些值(即 Y < 4 不正确的地方),然后形成剩余输入列表的列表其中 Y 成为这些值。结果由 Y * 2 变换,因此此时 [1,2] 变为 [2,4].

list comprehension 末尾 guard 的 return 值 Y < 4 不会包含在最终列表中,相反,如果它的计算结果为 false 列表中的当前元素将被排除在最终列表中,如果它的计算结果为 true,该元素将被包含。

在您的示例中,因为 5 不小于 4,所以它不包含在最终列表中,即 [2,4]

列表推导式 [Y * 2 || Y <- Ys, Y < 4] 直接等同于对列表的筛选和 然后 乘法。考虑到你不能 multiply false * 2 即使这是列表理解中的守卫的意思。

过滤器 test 看起来像 fun(Y) -> Y < 4 end 只是 return 一个布尔值 :

-spec my_test(integer()) -> boolean().
my_test(Y) -> Y < 4.

要将其组合成一个函数,return 是一个布尔值 一个整数,您需要一些不同的东西:

-spec multiply_or_false(integer()) -> integer() | false.
multiply_or_false(Y) ->
    case Y < 4 of
         true  -> Y * 2;
         false -> false
    end.

这是一个比较然后一个基于结果的分支return是false或一个整数。

如果您确实想要 return 加倍或布尔值,您可以在地图或列表理解中使用上面的 multiply_or_false/1 之类的东西(在这种情况下它们完全相同):

[multiply_or_false(Y) || Y <- Ys].

lists:map(fun multiply_or_false/1, Ys).

有时强迫自己将代码的元素分解成微小的函数并规范它们只是为了弄清楚你脑海中真正发生的事情是有用的(无论代码最终是否保持这种形式).