【发布时间】:2020-05-31 12:31:56
【问题描述】:
您好,我有以下代码可以按预期工作,但是当我在 Option.defaultWith 函数中进行模式匹配时,编译器会警告我模式匹配不完整。有没有更聪明的方法来达到同样的效果但没有警告?
我一直在考虑为其余情况抛出异常,但这很丑。
namespace JsonParser
open System
open System.Globalization
open FSharp.Data
open FSharp.Data.Runtime
type public Key = string
type public Value =
| Int of int
| Double of double
| Decimal of decimal
| String of string
| DateTime of DateTime
| Boolean of Boolean
| Array of Value []
| Guid of Guid
| Null
| Object of Record []
and public Record =
{ Key: Key
Value: Value }
module public Json =
let private culture = CultureInfo.InvariantCulture
let private emptyArray = Array.empty<String>
let rec private map (value: JsonValue) =
JsonConversions.AsInteger culture value
|> Option.map Value.Int
|> Option.orElseWith (fun () -> JsonConversions.AsDecimal culture value |> Option.map Value.Decimal)
|> Option.orElseWith (fun () -> JsonConversions.AsFloat emptyArray true culture value |> Option.map Decimal |> Option.map Value.Decimal)
|> Option.orElseWith (fun () -> JsonConversions.AsGuid value |> Option.map Value.Guid)
|> Option.orElseWith (fun () -> JsonConversions.AsDateTime culture value |> Option.map Value.DateTime)
|> Option.orElseWith (fun () -> JsonConversions.AsBoolean value |> Option.map Value.Boolean)
|> Option.defaultWith (fun () ->
match value with
| JsonValue.String x -> Value.String x
| JsonValue.Null -> Value.Null
| JsonValue.Array x ->
x
|> Array.map map
|> Value.Array
| JsonValue.Record x ->
x
|> Array.map (fun (x, y) ->
{ Key = x
Value = map y })
|> Value.Object)
【问题讨论】:
-
你为什么不只匹配 JsonValue.Null (等),在字符串的情况下,你可以尝试解析为 DateTime、Guid 等。你的代码会(IMO)更具可读性.
-
是的,这是个好主意。我今天实施了类似的方法。但是,充分利用
JsonValue的最佳做法是什么? -
我认为 JsonValue 可区分联合的全部意义在于,您可以将解析后的值与它进行匹配以确定它的真正含义。你已经在做,但是在你运行完所有那些 Option.orElseWith 语句之后。直接匹配就行了。这有帮助吗?
-
但对于我想要解析的情况,例如
Guid和DateTime。它需要我将JsonValue.String传递给一个额外的解析函数。在我的理想情况下,我希望在包含这些情况的情况下进行简单的模式匹配。