Notation "a +$+ b" := (IOStreamWriter.append (fun _ => a) (fun _ => b))
(at level 60, right associativity).
(* This is the monad used to write deserializers. It is a state monad with failure, where the state is the serialized bits. *)
Module ByteListReader : READER.
Definition t (A : Type) := list byte -> option (A * list byte).
Definition unwrap {A} (x : t A) := x.
Definition getByte (l : list byte) :=
match l with
| [] => None
| b :: l => Some (b, l)
end.
Definition ret {A} (a : A) : t A := fun s => Some (a, s).
Definition bind {A B} (m : t A) (f : A -> t B) : t B :=
fun s => match m s with None => None
| Some (a, s') => f a s'
end.
Definition map {A B} (f : A -> B) (d : t A) : t B :=
bind d (fun a => ret (f a)).
Definition error {A} : t A :=
fun l => None.

Lemma getByte_unwrap : forall l,
unwrap getByte l = match l with
| [] => None
| b :: l => Some (b, l)
end.