Section BasicCombinators.
Variables A B : Type.
Variable sA : Serializer A.
Variable sB : Serializer B.
Definition option_serialize (x : option A) : IOStreamWriter.t :=
match x with
| Some a => IOStreamWriter.append (fun _ => serialize true)
(fun _ => serialize a)
| None => serialize false
end.
Definition option_deserialize : ByteListReader.t (option A) :=
b <- deserialize ;;
match b with
| true => Some <$> deserialize
| false => ByteListReader.ret None
end.
Proof using.
intros.
unfold option_serialize, option_deserialize.
destruct a;
repeat (cheerios_crush; simpl).
Qed.
Global Instance option_Serializer : Serializer (option A).
Definition pair_serialize (x : A * B) : IOStreamWriter.t :=
let (a, b) := x in IOStreamWriter.append (fun _ => serialize a)
(fun _ => serialize b).
Definition pair_deserialize : ByteListReader.t (A * B) :=
a <- deserialize ;;
b <- deserialize ;;
ByteListReader.ret (a, b).
Proof using.
intros.
unfold pair_serialize, pair_deserialize.
destruct a.
cheerios_crush.
Qed.
Global Instance pair_Serializer : Serializer (A * B).
Definition sum_serialize (x : A + B) : IOStreamWriter.t :=
match x with
| inl a => IOStreamWriter.append (fun _ => serialize true)
(fun _ => serialize a)
| inr b => IOStreamWriter.append (fun _ => serialize false)
(fun _ => serialize b)
end.
Definition sum_deserialize : ByteListReader.t (A + B) :=
b <- deserialize ;;
match b with
| true => inl <$> deserialize
| false => inr <$> deserialize
end.

Lemma sum_serialize_deserialize_id :
serialize_deserialize_id_spec sum_serialize sum_deserialize.