elm-community / maybe-extra

Convenience functions for working with Maybe.

Home Page:http://package.elm-lang.org/packages/elm-community/maybe-extra/latest

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Function for `map >> withDefault`?

skyqrose opened this issue · comments

I often find myself writing

maybeX
|> Maybe.Map (\x -> x+1)
|> Maybe.withDefault 0

before realizing it's just a case.

case maybeX of
  Just x -> x + 1
  Nothing -> 0

But sometimes it's nice to be able to have a function instead of a multi-line case. (To be consise, so you can put it in a pipeline, so you can curry it and pass it to List.map, etc).

What would people think about a function : b -> (a -> b) -> Maybe a -> b that turns that standard case statement into a function?


In elixir, the case would look something like

case maybeX do
  nil -> 0
  x -> x + 1
end

but you can put case statements in a pipeline by omitting the argument

maybeX
|> case do
  nil -> 0
  x -> x + 1
end

(Though elixir doesn't have currying so that's not a normal function, it only works in pipelines.)

Elm is not currently planning on adding this "curry an argument into a case expression" feature or having functions with cases built into their arguments. The potential workarounds are:

  • Structure your code (e.g. by breaking up a pipeline) to use the case. (The first code snippet from this stack overflow question)
  • Use a lambda to turn the case expression into a function (the third snipped from that question).
  • Use Maybe.map and Maybe.withDefault as in my first example above.
  • Have a helper function (this proposal).

This idea was inspired by seeing this example of a small repo defining its own function to do this. I expect this is a pretty general need that could belong in this package.

Open questions:

  • Would this function be better than the existing workarounds?
  • Should the argument order be : b -> (a -> b) -> Maybe a -> b or : (a -> b) -> b -> Maybe a -> b? (List.foldl which this is pretty similar to has the base/default case after the function/reducer.)
  • What should it be named? mapDefault? Something with case in the name?

Oh wait, this is just unwrap. We already have this. Nevermind.

I think in the next major version bump I might rename that function to make the similarity to a case expression more clear. The name "unwrap" makes me think of assuming the value is always there, which is something to be avoided, rather than a "case" where checking the Maybe to decide what to do is a normal part of using a Maybe.