How to pass a function of arity 2 as an argument in Elixir for Enum.map?
Asked Answered
H

1

14

Let's say I have something like:

Enum.map(list, fn(x) -> String.duplicate("a", someValue * x) end)

But instead, I'd like to pass the String.duplicate/2 function as an argument in order to simplify my code:

Enum.map(list, &String.duplicate/2)

I know you can do it for arity 1 functions:

Enum.map(list, &String.downcase/1)

Thanks!

Henchman answered 13/11, 2015 at 15:32 Comment(0)
F
27

You can't pass a function to Enum.map with an arity of 2 as Enum.map calls your function with each element in the list as an argument. If you use another function like Enum.reduce then it expects a function with an arity of 2.

This is an example of the String.downcase/1 function being called with each item in the list:

Enum.map(["FOO", "BAR", "BAZ"], fn(x) -> String.downcase(x) end)
# String.downcase("FOO")
# String.downcase("BAR")
# String.downcase("BAZ")

In your example with duplicate, you are trying to call String.duplicate/2 with a single argument (the string "FOO").

You can use the capture syntax to create a function (this is a shorthand way of defining the function you provided):

Enum.map([1,2,3], &String.duplicate("a", &1))

You can also define a named function in your module that only requires one argument, for example:

Enum.map([1, 2, 3], &duplicate_foo/1)

def duplicate_foo(times), do: String.duplicate("a", times)
Flotation answered 13/11, 2015 at 15:35 Comment(1)
Small addition: In your second example, you can omit one level of parentheses like this: Enum.map([1,2,3], &String.duplicate("a", &1))Cutthroat

© 2022 - 2024 — McMap. All rights reserved.