List Comprehensions

Strict generators — <:- for lists and maps, <:= for binaries — raise an error instead of silently skipping elements that don't match the pattern:

[X * 2 || X <- [1, 2, 3]].                          % [2,4,6]
[X || X <- lists:seq(1, 10), X rem 2 =:= 0].        % [2,4,6,8,10]
[{X, Y} || X <- [1, 2], Y <- [a, b]].               % cartesian product
[V || {ok, V} <- [{ok, 1}, {error, x}, {ok, 3}]].   % pattern filter: [1,3]
[X || X <- [1, 2, 3], X > 1, X < 3].                % multiple filters

11.1 Binary comprehensions

<< <<(X * 2)>> || <<X>> <= <<1, 2, 3>> >>.          % <<2,4,6>>
[X || <<X:8>> <= <<"abc">>].                        % [97,98,99]
<< <<C>> || C <- "hello", C =/= $l >>.              % <<"heo">>

11.2 Map comprehensions (OTP 26+)

#{K => V * 2 || K := V <- #{a => 1, b => 2}}.       % #{a => 2, b => 4}
[K || K := _ <- #{x => 1, y => 2}].

11.3 Strict generators (OTP 28+)

Strict generators — <:- for lists and maps, <:= for binaries — raise an error instead of silently skipping elements that don't match the pattern:

[X || {ok, X} <:- [{ok, 1}, {ok, 2}]].     % [1,2]; an {error, _} element would raise

11.4 Classic examples

%% Quicksort
qsort([]) -> [];
qsort([P | T]) ->
    qsort([X || X <- T, X < P]) ++ [P] ++ qsort([X || X <- T, X >= P]).

%% Pythagorean triples
pyth(N) ->
    [{A, B, C} || A <- lists:seq(1, N), B <- lists:seq(A, N), C <- lists:seq(B, N),
                  A * A + B * B =:= C * C].

%% Permutations
perms([]) -> [[]];
perms(L) -> [[H | T] || H <- L, T <- perms(L -- [H])].

🧪 Part I Exercises

Write power(X, N) tail-recursively.

Implement my_lists:max/1, my_lists:last/1, my_lists:flatten/1.

Write fizzbuzz/1 that returns a list for 1..N using a case on {N rem 3, N rem 5}.

Implement range(From, To) without lists:seq.

Write compress/1 removing consecutive duplicates.

Implement count_occurrences(Elem, List) with a fold.

Write a module temp that converts between Celsius and Fahrenheit using tagged tuples {c, 20} / {f, 68}.

Write is_palindrome/1 for strings (ignore case and spaces).

Implement merge sort.

Write a maybe-based function that parses two strings into integers and divides them, returning {error, Reason} on failure.