I am teaching myself F#--For Fun and Profit!--and, while I've made some strides, I have run into a stumbling block with usage of algebraic types. Below is a JSON type that I coded to serialize an arbitrary JSON structure to a string. I am open to subjective comments on it's design and efficiency, of course, but I am mainly focussed on line 7:
type JSON =
| JString of string
| JNumber of decimal
| JBool of bool
| JNull
| JArray of JSON list
| JObject of Map< JSON, JSON >
with
member this.Serialize =
let rec serialize ( element : JSON ) =
match element with
| JString str ->
"\"" + str + "\""
| JNumber num ->
num.ToString()
| JBool bln ->
bln.ToString().ToLower()
| JNull ->
"null"
| JArray ary ->
"[" + String.concat "," ( List.map serialize ary ) + "]"
| JObject obj ->
"{" + (
Map.fold (
fun state key value ->
state + ( match state with "" -> "" | _ -> "," )
+ ( serialize key )
+ ":"
+ ( serialize value ) ) "" obj ) + "}"
serialize( this )
Anyone familiar with JSON knows that a key/value pair of a JSON object should be keyed on a string, not just any JSON element/value. Is there a way to further restrict the first type parameter of the Map? These, of course, do not work:
type JSON =
... elided ...
| JObject of Map< JSON.JString, JSON >
...
type JSON =
... elided ...
| JObject of Map< JString, JSON >
...
type JSON =
... elided ...
| JObject of Map< string, JSON >
Thanks.