concatMap
lib.lists.concatMap
Primop
Docs pulled from | This Revision | 3 days ago
Nixpkgs manual
Map and concatenate the result.
Type
concatMap :: (a -> [b]) -> [a] -> [b]
Examples
lib.lists.concatMap usage example
concatMap (x: [x] ++ ["z"]) ["a" "b"]
=> [ "a" "z" "b" "z" ]
Nix manual
Takes 2 arguments
f, list
This function is equivalent to builtins.concatLists (map f list)
but is more efficient.
Time Complexity
O(k * T_f + N) where:
k = length of input list
T_f = time to call f on an element
N = total number of elements returned by f calls
Noogle detected
Implementation
This function is implemented in c++ and is part of the native nix runtime.
static void prim_concatMap(EvalState & state, const PosIdx pos, Value ** args, Value & v)
{
state.forceFunction(*args[0], pos, "while evaluating the first argument passed to builtins.concatMap");
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.concatMap");
auto nrLists = args[1]->listSize();
// List of returned lists before concatenation. References to these Values must NOT be persisted.
SmallTemporaryValueVector<conservativeStackReservation> lists(nrLists);
size_t len = 0;
for (size_t n = 0; n < nrLists; ++n) {
Value * vElem = args[1]->listView()[n];
state.callFunction(*args[0], *vElem, lists[n], pos);
state.forceList(
lists[n],
lists[n].determinePos(args[0]->determinePos(pos)),
"while evaluating the return value of the function passed to builtins.concatMap");
len += lists[n].listSize();
}
auto list = state.buildList(len);
auto out = list.elems;
for (size_t n = 0, pos = 0; n < nrLists; ++n) {
auto listView = lists[n].listView();
auto l = listView.size();
if (l)
memcpy(out + pos, listView.data(), l * sizeof(Value *));
pos += l;
}
v.mkList(list);
}
Implementation
The following is the current implementation of this function.
concatMap = builtins.concatMap;