Notation "a +$+ b" := (IOStreamWriter.append (fun _ => a) (fun _ => b))
                      (at level 60, right associativity).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.

(* Specifications: *)
Lemma getByte_unwrap : forall l, unwrap getByte l = match l with | [] => None | b :: l => Some (b, l) end.
Lemma bind_unwrap : forall A B (m : t A) (f : A -> t B) bytes, unwrap (bind m f) bytes = match unwrap m bytes with | None => None | Some (v, bytes) => unwrap (f v) bytes end.