如何使用 Elmish 调试器解决编码器问题?
How do I solve encoder problem with the Elmish Debugger?
我有一个使用 websockets 在 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
在浏览器控制台中给出以下错误消息:
谁能告诉我如何解决这个问题? (假设它是可以修复的并且我已经正确诊断出问题。)谢谢。
您看到此错误是因为 Elmish.Debugger 使用 Thoth.Json 将您的 Msg/Model 序列化为 JSON 格式。
类型 WsSender
不能用 JSON 格式表示,因为它是一个函数。所以 Thoth.Json 要求你解释它应该如何编码这种类型。
您可以通过创建所谓的 extraCoder
来做到这一点:
在你的情况下,你将不得不创建一个假的 encoder/decoder "just" 来让调试器满意。
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
我尝试了一些尝试,想出一些可以在需要时更容易拥有多个额外编码器的东西。这似乎有效 - 认为它可能对其他人有帮助。
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
如果有人对如何操作有更好的想法,我很乐意根据他们的建议更新此答案。此外,泛型类型中的撇号似乎打乱了上面的代码美化器——我需要做些什么来解决这个问题吗?
我有一个使用 websockets 在 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
在浏览器控制台中给出以下错误消息:
谁能告诉我如何解决这个问题? (假设它是可以修复的并且我已经正确诊断出问题。)谢谢。
您看到此错误是因为 Elmish.Debugger 使用 Thoth.Json 将您的 Msg/Model 序列化为 JSON 格式。
类型 WsSender
不能用 JSON 格式表示,因为它是一个函数。所以 Thoth.Json 要求你解释它应该如何编码这种类型。
您可以通过创建所谓的 extraCoder
来做到这一点:
在你的情况下,你将不得不创建一个假的 encoder/decoder "just" 来让调试器满意。
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
我尝试了一些尝试,想出一些可以在需要时更容易拥有多个额外编码器的东西。这似乎有效 - 认为它可能对其他人有帮助。
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
如果有人对如何操作有更好的想法,我很乐意根据他们的建议更新此答案。此外,泛型类型中的撇号似乎打乱了上面的代码美化器——我需要做些什么来解决这个问题吗?