Much of Elm's power stems from the fact that most things are just functions. So how do operators fit in?
2 min read
By Robin Heggelund Hansen
December 12, 2020
Imagine that we have a list of first names (like Stanly, Paul and so forth), and another list of last names (Henderson, Hansen, Copperfield etc.). Also imagine that we have been given a task to come up with a set of full names, to be used as an example for a form we're making. We could solve the problem like so:
exampleNames : List String exampleNames = List.map2 (\firstName lastName -> firstName ++ lastName) listOfFirstNames listOfLastNames
This works, but the anonymous function we've made takes up a surprisingly large amount of screen real estate considering how little it actually does.
We could try to improve the situation by turning this into a proper function:
combineStrings : String -> String -> String combineStrings left right = left ++ right exampleNames : List String exampleNames = List.map2 combineStrings listOfFirstNames listOfLastNames
This works, but creating a function which just applies the ++ operator feels like more work than should be necessary.
The good news is that it is, in fact, uneccessary. Operators are functions, too.
Operators are special as they're the only functions which can be used with infix notation. That means its arguments are placed on both sides of the function. However, you can turn an operator back into a "regular" function by wrapping it with parenthesees, like this:
combineStrings : String -> String -> String combineStrings left right = (++) left right
As long as they're wrapped by parenthesees, operators work like any other function in Elm. Which means we could write the original exampleNames implementation like so:
exampleNames : List String exampleNames = List.map2 (++) listOfFirstNames listOfLastNames
You might have noticed that we have a bug here. Normally, a full name will have its first and last name seperated by whitespace, but our current implementation will join the first and last name without any space between them.
We could solve this by prefixing all last names with a single space, and then combine first names and last names together. Since operators are just functions, this allows us to make use of partial application:
exampleNames : List String exampleNames = List.map ((++) " ") listOfLastNames |> List.map2 (++) listOfFirstNames
While operators work differently from regular functions by default, you can make them work like any regular function by wrapping them in parentheses. Done correctly, this can make your code more succinct and easier to read.