1

I need to unwrap a Maybe -value in one of my update functions:

update msg model =

  case msg of

    UpdateMainContent val ->
      Maybe.withDefault 100 (Just 42)
      model

This of course is dummy code and the

 Maybe.withDefault 100 (Just 42)

is taken straight out of the documentation for Maybe and not supposed to actually do anything. The compiler is complaining and saying:

Detected errors in 1 module.


-- TYPE MISMATCH ----------------------------------- ./src/Review/Form/State.elm

The 1st argument to function `withDefault` is causing a mismatch.

15|>             Maybe.withDefault 100 (Just 42))
16|             -- Maybe.withDefault 100 (model.activeItem)
17|             model

Function `withDefault` is expecting the 1st argument to be:

    a -> b

But it is:

    number

Why is it saying that "withDefault" is expecting the first argument to be

a -> b

when it is defined as

a -> Maybe a -> a

in the documentation?

swelet
  • 8,192
  • 5
  • 33
  • 45
  • Looks like you have some weird syntax error in your code and compiler fails to recognize it. Try wrapping `(Maybe.withDefault 100 (Just 42))` or adding more code it to your example. – halfzebra Aug 09 '16 at 07:25
  • @halfzebra that gives exactly the same error. I don't want to paste the full code path since it's big, nested and modular and that would make the question a bit to specific. However I can say that "val" is just a simple string coming in. So what you are saying is that I can have a syntax error outside of the code above that causes the error? Ill try to clarify my question a bit. – swelet Aug 09 '16 at 08:16

1 Answers1

8

You accidentally left in model:

UpdateMainContent val ->
  Maybe.withDefault 100 (Just 42)
  model --  <-- here

This makes the type inference algorithm think that Maybe.withDefault 100 (Just 42) should evaluate to a function that can take this model argument. For that to make sense, it expects 100 and 42 to be functions, but they aren't, and so it tells you.

It might help to see an example where this works:

f : Int -> Int
f x = x + 1

Maybe.withDefault identity (Just f) 0 

This will evaluate to 1.

Søren Debois
  • 5,598
  • 26
  • 48
  • Thank you Sören! How can I rewrite it to avoid this? Just wrapping it in parens : (Maybe.withDefault 100 (Just 42)) gives the same error! – swelet Aug 09 '16 at 08:24
  • 1
    Delete the line with `model`? – Søren Debois Aug 09 '16 at 08:26
  • I need the case to return "model". I think I am missing something here (pretty new to functional programming). Isn't it possible to execute some arbitrary code before returning something from a case? – swelet Aug 09 '16 at 09:10
  • You want the `Maybe.withDefault ...` to somehow result in the model that should be returned. (Maybe this line of questions is better suited for the elm-slack, [#help](https://elm.slack.com/messages/help) or [#beginners](https://elm.slack.com/messages/beginners)?) – Søren Debois Aug 09 '16 at 09:17
  • PS. If you think this answer is helpful, consider accepting it so that others can see it's helpful (and so I get the oh-so-gratifying little green +15 ;). – Søren Debois Aug 10 '16 at 08:26
  • you don't need to 'return model' but to return an updated model. If you provide the code for your model we can provide a better answer – Simon H Aug 10 '16 at 11:46
  • 1
    If you want to first so some calculations before returning something (an updated model), you can use the `let ...(calculations here)... in ...(your return value here)` construct of Elm. – wintvelt Aug 11 '16 at 19:27
  • I suppose the let statement behaviour was what I was looking for! – swelet Aug 12 '16 at 07:02