Module listcomp
Authors: Serge Aleynikov (saleyn(at)gmail(dot)com).
Description
Erlang map-reduce parse transform
This transform introduces two modifications of the list comprehension syntax that allow to perform a fold and mapfold on a list.
Indexed List Comprehension
This extension of a list comprehension, passes an additional argument to the left hand side of the comprehension, which is the index of the current item in the list: [ io:format("Rec#~w: ~p\n", [I, N]) || I, N <- L]
^^
```
The index is defined by the a variable listed after the `||' operator.
This is equivalent to the following:
```
lists:mapfoldl(
fun(N, I) ->
io:format("Rec#~w: ~p\n", [I, N]),
I+1
end, 1, L)
```
=== Fold Comprehension ===
To invoke the fold comprehension transform include the initial state
assignment into a comprehension that returns a non-tuple expression:
```
[S+N || S = 1, N <- L].
^^^ ^^^^^
In this example the S
variable gets assigned the initial state 1
, and
the S+N
expression represents the body of the fold function that
is passed the iteration variable N
and the state variable S
:
lists:foldl(fun(N, S) -> S+N end, 1, L).
Fold comprehension can be combined with the indexed list comprehension:
[running_sum(I, N, S+N) || I, S=5, N <- L].
running_sum(I, N, RunningSum) ->
io:format("Rec#~w: ~p (~w)\n", [I, N, RunningSum]),
S.
In this case the definition of the indexed fold comprehension would be
transformed to:
element(2, lists:foldl(fun(I, {N, S}) ->
running_sum(I, N, S), {N+1, S+N} end, {1,5}, L)),
Compilation
When using this as a parse transform, include the
{parse_transform,listcomp}
compiler option.
erlc
compiler:
-Dlistcomp_orig
- print the original AST before the transform-Dlistcomp_ast
- print the transformed AST-Dlistcomp_src
- print the resulting source code after the transformFunction Index
foldl/3 | Fold over a list by additionally passing the list's current item number to the folding fun. |
foldr/3 | Fold over a list by additionally passing the list's current item number to the folding fun. |
parse_transform/2 | parse_transform entry point. |
Function Details
foldl/3
foldl(Fun ::
fun((Position :: integer(),
Item :: term(),
Acc :: term()) ->
NewAcc :: term()),
Init :: term(),
List :: list()) ->
term()
Fold over a list by additionally passing the list's current item number to the folding fun. This function is similar to lists:foldl/3, except that the fun takes the extra second integer argument that represents the sequential number of the item from the list.
foldr/3
foldr(Fun ::
fun((Position :: integer(),
Item :: term(),
Acc :: term()) ->
NewAcc :: term()),
Init :: term(),
List :: list()) ->
term()
Fold over a list by additionally passing the list's current item number to the folding fun. This function is similar to lists:foldr/3, except that the fun takes the extra second integer argument that represents the sequential number of the item from the list.
parse_transform/2
parse_transform(AST, Options) -> any()
parse_transform entry point