Set F # list to null for serialization
I am using F # alongside a JSON data store using the JSON.NET library. I am trying to use F # structs and types where possible and am faced with the following problem. Let's say I want to keep the following data structure,
type A = {
id : int
name : string
posts : string list
}
Creation works fine, but to update only the saved field, name
I need to send a JSON record that did not specify the field posts
. Using an empty list will not work because the save system will assume that I want to replace existing entries with an empty list and thus overwrite them. From JSON.NET docs I read a field that can be excluded from serialization by setting it to null
,
let updatedEntry = { id : 0, name : "Fred", posts = null }
However, the F # compiler will throw an error stating that the type list
cannot be set to null
. Is there a way to do this from within F #, possibly with an attribute that I am not aware of? Thanks to
source to share
There are two ways to do this easily:
Option 1
Use the System.Collections.Generic.List type, which can be null:
> type A = {id: int; name:string; posts: System.Collections.Generic.List<string> };;
type A =
{id: int;
name: string;
posts: System.Collections.Generic.List<string>;}
> let a = {id=5; name="hello"; posts=null};;
val a : A = {id = 5;
name = "hello";
posts = null;}
Option 2
Another, more idiomatic way would be to use the Option type:
> type A = {id: int; name:string; posts: string list option };;
type A =
{id: int;
name: string;
posts: string list option;}
> let a = {id=5; name="there"; posts=None};;
val a : A = {id = 5;
name = "there";
posts = null;}
Note that you are comparing the element posts
with None
, not null
.
Convenient Reading: Option Types
Edit
(After some searching and experimenting) you can use boxing to use F # types as values:
> type A = {id: int; name:string; posts: System.Object };;
type A =
{id: int;
name: string;
posts: Object;}
> let a = {id=5; name="foo"; posts=null};;
val a : A = {id = 5;
name = "foo";
posts = null;}
> let b = {id=6; name="bar"; posts=(box [])};;
val b : A = {id = 6;
name = "bar";
posts = [];}
But I would stick with Option type, personally
source to share