Search code examples
functionenumsfunctional-programmingelixirarity

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


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!


Solution

  • 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)