Skip to content

Instantly share code, notes, and snippets.

@matarillo
Created November 26, 2024 10:38
Show Gist options
  • Save matarillo/9c5f613743357826735339330e5f2588 to your computer and use it in GitHub Desktop.
Save matarillo/9c5f613743357826735339330e5f2588 to your computer and use it in GitHub Desktop.
コンピュテーション式を使わない書き方
module Json
open System.Text
[<AbstractClass>]
type JNode() =
abstract member Stringify: unit -> string
[<AbstractClass>]
type JValue() =
inherit JNode()
static member Null: JValue =
{ new JValue() with
member _.Stringify() = "null" }
let encodeString (value: string) =
let escaped = value.Replace("\"", "\\\"")
"\"" + escaped + "\""
type JString(value: string) =
inherit JValue()
member _.Value: string = value
override _.Stringify() = encodeString value
type JBool(value: bool) =
inherit JValue()
member _.Value: bool = value
override _.Stringify() = value.ToString()
type JNumber(value: decimal) =
inherit JValue()
member _.Value: decimal = value
override _.Stringify() = value.ToString()
type JArray(array: JNode array) =
inherit JNode()
override _.Stringify() =
match array with
| [||] -> "[]"
| [| x |] -> $"[{x.Stringify()}]"
| [| x; y |] -> $"[{x.Stringify()}, {y.Stringify()}]"
| _ ->
let folder (sb: StringBuilder) (jn: JNode) =
if sb.Length = 0 then
sb.Append(jn.Stringify())
else
sb.Append ", " |> ignore
sb.Append(jn.Stringify())
let sb = Array.fold folder (StringBuilder()) array
$"[{sb}]"
let encodeProperty (k: string, v: JNode) = $"{encodeString k}: {v.Stringify()}"
type JObject(props: (string * JNode) array) =
inherit JNode()
override _.Stringify() =
match props with
| [||] -> "{}"
| [| k, v |] -> $"{{{encodeProperty (k, v)}}}"
| _ ->
let folder (sb: StringBuilder) (k, v) =
if sb.Length = 0 then
sb.Append(encodeProperty (k, v))
else
sb.Append ", " |> ignore
sb.Append(encodeProperty (k, v))
let sb = Array.fold folder (StringBuilder()) props
$"{{{sb}}}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment