0

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

这段代码在几天前就开始工作了。

为应用级别消息键入 misMatch

App.fs 片段

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

4

1 回答 1

3

match里面的两个分支App.update有不同的类型。第一个分支有 type App.Model * Cmd<ConnectionPage.Msg>,第二个页面有 type App.Model * Cmd<CodeGenPage.Msg>

你一般不能这样做。例如,这不会编译:

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

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


要转换Cmd<ConnectionPage.Msg>Cmd<App.Msg>(通过将消息包装在 中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
于 2020-06-14T18:42:59.017 回答