Guilhem Soulas
Guilhem Soulas

Reputation: 1995

Elm - StartApp type issue

I have a Main module that imports a Users module (without exposing anything).

In Main I'm using startApp the normal way, using only definitions from the Main module:

app =
  StartApp.start
    { init = init
    , inputs = [Signal.map TopBar topBarActionPort]
    , update = update
    , view = view
    }

But Elm Reactor is complaining and is trying to use the Users module which doesn't make sense. See message below.

Function start is expecting the argument to be:

{ ...
, inputs : List (Signal Users.Action)
, update : Users.Action -> Model -> ( Model, Effects Users.Action )
, view : Address Users.Action -> Model -> Html
}

But it is:

{ ...
, inputs : List (Signal Action)
, update : Action -> Model -> ( Model, Effects Action )
, view : Address Action -> Model -> Html
}

How to make the compiler use the Main module functions as it should be??

Upvotes: 0

Views: 47

Answers (1)

Chad Gilbert
Chad Gilbert

Reputation: 36385

This is usually indicative of a type inference error that "bubbles up" to start.

Type annotations are not required in Elm, and if you don't explicitly give the function a type signature, Elm will infer it.

For a trivial example - suppose I had these two functions:

getUsers = { name = "Bob", age = 42 }

getUserNames = List.map .name getUsers -- compiler error!

The name of getUsers seems to imply that it should return a list, but based on its return type, Elm compiles getUsers as type User instead of List User. Therefore, getUsers compiles just fine (albeit with an inferred type signature that you don't expect).

However, the compiler is going to tell you there is something wrong with the function getUserNames even though the problem originates in the fact that getUsers is incorrectly defined.

This bubbling up effect is probably why you're seeing weird compiler errors pointing at the start function. The way to track down which functions are incorrect is to add type annotations in all your modules.

Consider the trivial example above. If I were to annotate my functions, the compiler would then complain about the function at the root of the problem.

getUsers : List User
getUsers = { name = "Bob", age = 42 } -- compiler error!

getUserNames : List String
getUserNames = List.map .name getUsers

Elm's type inference is powerful and very useful, but it can sometimes cause odd and seemingly unrelated compiler errors if used in a deeply nested fashion. A good rule of thumb that has served me well is to annotate all publicly exposed functions in my modules.

Upvotes: 1

Related Questions