如何使用Elmish Debugger解决编码器问题?

时间:2020-04-20 15:38:13

标签: f# elmish safe-stack

我有一个使用websocket在SAFE-Stack中构建的应用程序,大致遵循以下方法:https://github.com/CompositionalIT/safe-sockets

工作正常,但Elmish调试器在此示例中不喜欢WsSender的类型:


type ConnectionState =
        | DisconnectedFromServer
        | ConnectedToServer of WsSender
        | Connecting

        member this.IsConnected =
            match this with
            | ConnectedToServer _ -> true
            | DisconnectedFromServer | Connecting -> false

    and WsSender = Msg -> Unit

在浏览器控制台中给出以下错误消息:

ElmishDebuggerMessage

谁能告诉我如何解决此问题? (假设它是可修复的,并且我已经正确诊断了问题。)谢谢。

2 个答案:

答案 0 :(得分:2)

由于Elmish.Debugger使用Thoth.Json将Msg / Model序列化为JSON格式,您看到此错误。

WsSender类型不能以JSON格式表示,因为它是一个函数。因此,Thoth.Json要求您解释它应该如何编码这种类型。

您可以通过创建像这样的extraCoder来做到这一点:

在您的情况下,您将不得不“伪造”一个伪造的编码器/解码器以使调试器满意。

module CustomEncoders =

    let wsSenderEncoder (_ : WsSender) = Encode.string "WsSender function"

    let wsSenderDecoder = Decode.fail "Decoding is not supported for WsSender type"

    let myExtraCoders =
        Extra.empty
        |> Extra.withCustom wsSenderEncoder wsSenderDecoder 


    let modelEncoder = Encode.Auto.generateEncoder(extra = myExtraCoders)
    let modelDecoder = Decode.Auto.generateDecoder(extra = myExtraCoders)

在创建程序时,应将Program.withDebugger替换为Program.withDebuggerCoders,并为其提供创建的编码器和解码器。

Program.withDebuggerCoders CustomEncoders.modelEncoder CustomEncoders.modelDecoder

答案 1 :(得分:0)

我有一些尝试,想出一些办法,如果需要的话,可以更轻松地拥有多个额外的编码器。这似乎可行-认为可能对其他人有所帮助。


module CustomEncoders =

    let inline addDummyCoder<'b> extrasIn =
        let typeName = string typeof<'b>
        let simpleEncoder(_ : 'b) = Encode.string (sprintf "%s function" typeName)
        let simpleDecoder = Decode.fail (sprintf "Decoding is not supported for %s type" typeName)
        extrasIn |> Extra.withCustom simpleEncoder simpleDecoder

    let inline buildExtras<'a> extraCoders =
        let myEncoder:Encoder<'a> = Encode.Auto.generateEncoder(extra = extraCoders)
        let myDecoder:Decoder<'a> = Decode.Auto.generateDecoder(extra = extraCoders)
        (myEncoder, myDecoder)

type TestType = Msg -> Unit
type TestType2 = string -> Unit

let extras = Extra.empty
                |> CustomEncoders.addDummyCoder<TestType>
                |> CustomEncoders.addDummyCoder<TestType2>
                |> CustomEncoders.buildExtras<Model.Model>


#if DEBUG
open Elmish.Debug
open Elmish.HMR
#endif


Program.mkProgram Model.init Model.update View.render
|> Program.withSubscription subs 
#if DEBUG
|> Program.withConsoleTrace
#endif
|> Program.withReactBatched "elmish-app"
#if DEBUG
|> Program.withDebuggerCoders (fst extras) (snd extras)
#endif
|> Program.run


如果有人对如何做有更好的主意,我很乐意用他们的建议来更新此答案。另外,泛型类型的撇号似乎使上面的代码修饰词不高兴-我需要做些什么来解决此问题?