我有一个Main
模块导入Users
模块(不暴露任何东西)。
在Main
我正常使用startApp,只使用Main
模块中的定义:
app =
StartApp.start
{ init = init
, inputs = [Signal.map TopBar topBarActionPort]
, update = update
, view = view
}
但Elm Reactor正在抱怨并且正在尝试使用Users
模块,这个模块没有意义。见下面的消息。
函数start
期望参数为:
{ ...
, inputs : List (Signal Users.Action)
, update : Users.Action -> Model -> ( Model, Effects Users.Action )
, view : Address Users.Action -> Model -> Html
}
但它是:
{ ...
, inputs : List (Signal Action)
, update : Action -> Model -> ( Model, Effects Action )
, view : Address Action -> Model -> Html
}
如何使编译器使用Main
模块函数,因为它应该是??
答案 0 :(得分:1)
这通常表示类型推断错误"冒泡"到start
。
在Elm中不需要输入注释,如果您没有明确地为该函数提供类型签名,Elm将推断它。
对于一个简单的例子 - 假设我有这两个函数:
getUsers = { name = "Bob", age = 42 }
getUserNames = List.map .name getUsers -- compiler error!
getUsers
的名称似乎暗示它应该返回一个列表,但根据其返回类型,Elm将getUsers
编译为类型User
而不是List User
。因此,getUsers
编译得很好(虽然推断的类型签名你不期望)。
但是,编译器会告诉您函数getUserNames
有问题,即使问题源于getUsers
未正确定义的事实。
这种冒泡效果可能是您看到指向start
函数的奇怪编译器错误的原因。跟踪哪些函数不正确的方法是在所有模块中添加类型注释。
考虑上面的小例子。如果我要注释我的函数,那么编译器就会在问题的根源上抱怨函数。
getUsers : List User
getUsers = { name = "Bob", age = 42 } -- compiler error!
getUserNames : List String
getUserNames = List.map .name getUsers
Elm的类型推断功能强大且非常有用,但如果以深度嵌套的方式使用,它有时会导致奇怪且看似无关的编译器错误。一个很好的经验法则是在我的模块中注释所有公开的函数。