Mapping over collections with each

There is a special built-in function called each which can be used to apply a function to every value of a collection. It can have any of the following types:

each : (a → b) × List(a) → List(b)
each : (a → b) × Bag(a) → Bag(b)
each : (a → b) × Set(a) → Set(b)

In other words, each takes two arguments: the first is a function of some arbitrary type a b, and the second is a collection (list, bag, or set) containing values of type a. each then applies the function to every element in the collection, returning the same kind of collection but now full of b values instead of a. (a and b can be different types, but they do not have to be.)

For example, we can use each to take the absolute value of every integer in a set, or multiply every value in a set by 10:

Disco> each(abs, {-3 .. 2})
{0, 1, 2, 3}
Disco> each(\x. x*10, {1,2,3,7})
{10, 20, 30, 70}

Notice how in the second example above we use an anonymous function as the first argument to each. We can also apply each to a list or bag:

Disco> each(\x. x // 2, [0 .. 6])
[0, 0, 1, 1, 2, 2, 3]
Disco> import num
Disco> each(\x. x + 1, factor(60))
⟅3 # 2, 4, 6⟆

Note that it is always possible to use a comprehension instead of each, if you prefer. For example, instead of writing each(\x. x * 10, {1,2,3,7}) we could write

Disco> {x*10 | x in {1,2,3,7}}
{10, 20, 30, 70}

However, each is more fundamental (in fact, comprehensions are implemented in terms of each) and in some cases may be more convenient.