Skip to content

Instantly share code, notes, and snippets.

@Savelenko
Last active June 24, 2021 11:06
Show Gist options
  • Save Savelenko/edee81abef0f3ea38e61d8a446860eb2 to your computer and use it in GitHub Desktop.
Save Savelenko/edee81abef0f3ea38e61d8a446860eb2 to your computer and use it in GitHub Desktop.
Church-encoded JSON in F#
/// Church-encoded JSON values.
type Json =
abstract Value<'r> :
(string -> 'r)
-> (bool -> 'r)
-> (decimal -> 'r)
-> (Map<string, Json> -> 'r)
-> (List<Json> -> 'r)
-> 'r
type ValueType = JString | JBool | JNumber | JObject | JArray
/// The type of the given JSON value.
let valueType (json : Json) : ValueType =
json.Value (fun _ -> JString) (fun _ -> JBool) (fun _ -> JNumber) (fun _ -> JObject) (fun _ -> JArray)
/// Constructor for a JSON string.
let jsonString (s : string) : Json = { new Json with
member _.Value isString _ _ _ _ = isString s
}
// And so on for booleans, numbers, objects and arrays.
/// Pattern match on JSON values.
let (|JString|JBool|JNumber|JObject|JArray|) (json : Json) =
json.Value Choice1Of5 Choice2Of5 Choice3Of5 Choice4Of5 Choice5Of5 // Kind of funny
let shouldBeString =
match jsonString "Hello" with
| JString hello -> hello
| _ -> failwith "Expected a string!"
// "Hello"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment