1

Why are the arguments ordered the way they are in Array.get and Dict.get? The order in most map/filter functions makes sense: the function comes before the collection (or monad, more generally).

MyCollection.map : (a -> b) -> MyCollection a -> MyCollection b

This makes it easier to compose higher functions out of smaller ones before passing in a collection.

Why, however, does the index/key come before the collection in get functions?

Dict.get : comparable -> Dict comparable v -> Maybe v

It seems to make it harder to compose higher functions. If the arguments were reversed, one could write:

ids : List Int
myObjects : Dict Int a

selectObjects = List.map (Dict.get myObjects) ids

But instead, the best way I can come up with to write this is:

ids : List Int
myObjects : Dict Int a

selectObjects = List.map (\id -> (Dict.get id myObjects)) ids

Am I missing something? What is the reason for the argument order in Array.get, Dict.get, and similar?

Eric
  • 1,511
  • 1
  • 15
  • 28
  • You could use [`flip`](http://package.elm-lang.org/packages/elm-lang/core/4.0.5/Basics#flip) to get rid of the lambda: `List.map (flip Dict.get myObjects) ids` – Chad Gilbert Aug 22 '16 at 19:02
  • I appreciate the suggestion, but I wasn't asking how to work around this, which is quite easy. I'd like to know the reasoning behind the argument order, since I'm not very experienced with FP and I'd like to know if there's some benefit the library design allows. – Eric Aug 22 '16 at 19:20
  • 1
    My guess is that it was designed to look like Haskell's [`Data.Map.lookup`](http://hackage.haskell.org/package/containers-0.5.7.1/docs/Data-Map-Strict.html#v:lookup) function which, coincidentally, is listed under the [bad examples](https://wiki.haskell.org/Parameter_order#Bad_examples) section of parameter ordering on the Haskell wiki. – Chad Gilbert Aug 22 '16 at 19:24

1 Answers1

3

List.map (Dict.get myObjects) ids isn't function composition.

Composition is when you have
f : X -> Y and
g : Y -> Z then you compose them
h = f >> g so that
h : X -> Z

Now, when composing functions as above, we need them to require ONLY one more parameter.

So when defining an API, the question is:
"When someone partially evaluates this function so that it can be composed, what is the last parameter they'll likely want to pass it?"

In other words, are we more likely to see code like:
getStuff >> mungeIntoDict >> (Dict.get id)
or
getStuff >> getImportantId >> (Dict.get myDict) ?

The answer to that is "it depends". The API designers took their best guess and we have flip for when it doesn't suit us.

Mark Bolusmjak
  • 23,606
  • 10
  • 74
  • 129