Reputation: 453
I am trying to work out an equation which is f(Ys) -> [Y * 2 || Y <- Ys, Y < 4].
.
When I input a list f([5,1,2,6]).
I get the result as [2,4]
whilst I thought it should be [10, false]
, which is derived from f([5,1,2,6]) -> [5 * 2 || 5 <- [1,2,6], 5 < 4]
.
Can anyone tell me where I got it wrong or possibly walk through the correct process about how the correct result is achieved?
Upvotes: 2
Views: 85
Reputation: 13154
The list comprehension [Y * 2 || Y <- Ys, Y < 4]
is directly equivalent to a filter over a list and then a multiplication. Consider that you couldn't multiply false * 2
even if that is what the guard in the list comprehension meant.
The filter test would look like fun(Y) -> Y < 4 end
, which only returns a boolean:
-spec my_test(integer()) -> boolean().
my_test(Y) -> Y < 4.
To combine this into a function that returns a boolean or an integer you need something different:
-spec multiply_or_false(integer()) -> integer() | false.
multiply_or_false(Y) ->
case Y < 4 of
true -> Y * 2;
false -> false
end.
This is a comparison and then a branch based on the outcome which returns either false
or an integer.
If you did want to return a doubling or a boolean, you could use something like multiply_or_false/1 above in a map or list comprehension (they are exactly equivalent in this case):
[multiply_or_false(Y) || Y <- Ys].
or
lists:map(fun multiply_or_false/1, Ys).
Sometimes it is useful to force yourself to break elements of your code down into tiny little functions and spec them just to clarify what is really going on in your mind (whether or not the code remains in that form in the end).
Upvotes: 3
Reputation: 2544
The return value of the guard
at the end of your list comprehension
, which is Y < 4
, won't be included in your final list, instead if it evaluates to false
the current element in the list will be excluded in the final list, and if it evaluates to true
, the element will be included.
In your example because 5
is not less than 4
, so it doesn't include in the final list which is [2,4]
.
Upvotes: 2
Reputation: 3729
Of your input list elements, [5,6]
are discarded because Y < 4
is false, leaving [1,2]
.
Your output is evaluated as Y * 2
so a result of [2,4]
works for me.
The list comprehension takes each value of Ys
and discards those which where the predicates aren't true (i.e. where Y < 4
is not true) and then forms a list of the remaining input list where Y becomes those values. The result is transformed by Y * 2
though, so at that point [1,2]
becomes [2,4]
.
Upvotes: 3