Skip to content

Instantly share code, notes, and snippets.

@greim
Last active January 14, 2017 23:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save greim/337a4f44a862466cf883cca89b149037 to your computer and use it in GitHub Desktop.
Save greim/337a4f44a862466cf883cca89b149037 to your computer and use it in GitHub Desktop.

Elm: Supplementary Notes

In which I get angry because some aspect of Elm seems... well, weird to me, and the docs aren't helping, so I jot down these notes in order to force myself to better grasp the topic, because writing forces me to think deeply about things in a way that I'm incapable of doing otherwise gaaasspp

Grokking Elm Functions

Background: In Elm, functions are pure. Given the same input, they'll always return the same output. That isn't the case in JavaScript, where for example a function can return different values on successive calls, like Math.random() or Date.now().

Thus, a function that takes zero args is conceptually no different than a variable. A variable holds a value. A zero-arg function only returns one possible value. This is reflected in Elm syntax. Look at how you annotate and declare a variable in Elm:

foo : Int
foo = 5

Then look at how you annotate and declare functions:

addOne : Int -> Int
foo x = x + 1

add : Int -> Int -> Int
foo x y = x + y

Notice the pattern? A two-arg function has two ->s on it. An one-arg has one, and a zero-arg has zero. There's literally no other difference. It's as if there were no variables in Elm, just functions with zero or more args.

Partial Application

Any function that takes N args, where N > 1, is also a function that takes fewer-than N args, and which returns a new function expecting the remaining args. Suppose we have a list of ints, and want a new list in which we've added 2 to every item. Obviously, we'll need a function to pass to List.map:

add2 : Int -> Int
add2 a = a + 2

myList : List Int
myList = [1, 2, 3];

otherList : List Int
otherList = List.map add2 myList

But suppose we already have a function which accepts two ints and adds them together:

add : Int -> Int -> Int
add a b = a + b

We can partially apply the add function in order to get our add2 function.

myList : List Int
myList = [1, 2, 3];

otherList : List Int
otherList = List.map (add 2) myList

Also notice that partial application only happens left-to-right. To partially-apply in the middle of the arg list, you have to write a custom function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment