【问题标题】:Why is is the compiler telling me "Type misMatch for App message" when they are the same type当它们是相同类型时,为什么编译器会告诉我“App 消息的类型不匹配”
【发布时间】:2020-06-14 18:16:46
【问题描述】:

所以,我一直在与编译器争论类型错误。

这段代码几天前还在工作。

为应用级消息键入 misMatch

App.fs sn-ps

module App =
    type Msg =
        | ConnectionPageMsg of ConnectionPage.Msg
        | CodeGenPageMsg of CodeGenPage.Msg
//...
    let update (msg : Msg) (model : Model) =
        match msg with
        | ConnectionPageMsg msg ->
            let m, cmd = ConnectionPage.update msg model.ConnectionPageModel
            { model with ConnectionPageModel = m }, cmd
        | CodeGenPageMsg msg ->
            let m, cmd = CodeGenPage.update msg model.CodeGenPageModel
            { model with CodeGenPageModel = m }, cmd
//...
    let runner =
        Program.mkProgram init update view
        |> Program.withConsoleTrace
        |> XamarinFormsProgram.run app

我添加了显式别名和原始错误:

Type mismatch. Expecting a
    'App.Msg -> App.Model -> App.Model * Cmd<App.Msg>'    
but given a
    'App.Msg -> App.Model -> App.Model * Cmd<Msg>'    
The type 'App.Msg' does not match the type 'Msg'

变成了这些:

App.fs(50,50): Error FS0001: The type 'PocoGen.Page.ConnectionPage.Msg' does not match the type 'PocoGen.Page.CodeGenPage.Msg' (FS0001) (PocoGen)
App.fs(32,32): Error FS0001: Type mismatch. 
Expecting a 'App.Msg -> App.Model -> App.Model * Cmd<App.Msg>'    
but given a 'App.Msg -> App.Model -> App.Model * Cmd<Msg>'    
The type 'App.Msg' does not match the type 'Msg' (FS0001) (PocoGen)

其他说明

就在这些错误开始出现之前,我正在将阻塞同步调用转换为 ConnectionTestPage 中的异步命令,并删除了 cmd 的调用代码,希望能够修复它。 (它没有)

ConnectionPage.fs 消息

type Msg =
    | UpdateConnectionStringValue of string
    | UpdateConnectionStringName of string
    | TestConnection
    | TestConnectionComplete of Model
    | SaveConnectionString of ConnectionStringItem
    | UpdateOutput of string

ConnectionPage.fs 更新

let update (msg : Msg) (m : Model) : Model * Cmd<Msg> =
    match msg with
    | UpdateConnectionStringValue conStringVal ->
        { m with
              ConnectionString =
                  { Id = m.ConnectionString.Id
                    Name = m.ConnectionString.Name
                    Value = conStringVal }
              CurrentFormState =
                  match hasRequredSaveFields m.ConnectionString with
                  | false -> MissingConnStrValue
                  | _ -> Valid }, Cmd.none

    | UpdateConnectionStringName conStringName ->
        { m with
              ConnectionString =
                  { Id = m.ConnectionString.Id
                    Name = conStringName
                    Value = m.ConnectionString.Value }
              CurrentFormState =
                  match hasRequredSaveFields m.ConnectionString with
                  | false -> MissingConnStrValue
                  | _ -> Valid }, Cmd.none

    | UpdateOutput output -> { m with Output = output }, Cmd.none
    | TestConnection -> m, Cmd.none
    | TestConnectionComplete testResult -> { m with Output = testResult.Output + "\r\n" }, Cmd.none
    | SaveConnectionString(_) -> saveConnection m, Cmd.none

我玩过 Fsharp 版本(因为顺便说一下,在收到此错误之前我确实更新到了 4.7.2

完整的回购:

https://github.com/musicm122/PocoGen_Fsharp/tree/master/PocoGen

【问题讨论】:

    标签: xamarin.forms f# elm-architecture


    【解决方案1】:

    App.update里面的match的两个分支有不同的类型。第一个分支的类型为App.Model * Cmd&lt;ConnectionPage.Msg&gt;,第二个页面的类型为App.Model * Cmd&lt;CodeGenPage.Msg&gt;

    您通常不能这样做。例如,这不会编译:

    let x = 
        match y with
        | true -> 42
        | false -> "foo"
    

    这里的x 是什么类型?是int 还是string?不计算。 match 表达式必须具有相同类型的所有分支。


    要将Cmd&lt;ConnectionPage.Msg&gt; 转换为Cmd&lt;App.Msg&gt;(通过将消息包装在ConnectionPageMsg 中),您可以使用Cmd.map

    let update (msg : Msg) (model : Model) =
        match msg with
        | ConnectionPageMsg msg ->
            let m, cmd = ConnectionPage.update msg model.ConnectionPageModel
            { model with ConnectionPageModel = m }, Cmd.map ConnectionPageMsg cmd
        | CodeGenPageMsg msg ->
            let m, cmd = CodeGenPage.update msg model.CodeGenPageModel
            { model with CodeGenPageModel = m }, Cmd.map CodeGenPageMsg cmd
    

    【讨论】:

    • 谢谢@fyodor-soikin 你太棒了。我认为应用程序消息歧视工会会为我做到这一点。我仍在尝试 grok Cmds 和 Cmd Messages。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 2015-10-01
    • 2019-07-22
    • 1970-01-01
    • 2014-01-18
    • 1970-01-01
    相关资源
    最近更新 更多