let of_yojson j =     let open Pvem.Result in     let error ?json fmt =       ksprintf (fun s ->           fail (sprintf "%s%s" s                   (Option.value_map ~default:"" json                      ~f:(fun j ->                          sprintf " but got %s" @@                          Yojson.Safe.pretty_to_string ~std:true j)))         ) fmt in     let data_of_yojson =       function       | `Assoc ["paired-end"`Assoc ["r1"`String r1; "r2"`String r2]] ->         return (PE (r1, r2))       | `Assoc ["single-end"`String file] -> SE file |> return       | `Assoc ["bam"`Assoc ["kind"`String kind;                                "sorting", sorting;                                "reference-genome"`String refb;                                "path"`String path;]] ->         begin match sorting with         | `Null -> return None         | `String "coordinate" -> Some `Coordinate |> return         | `String "read-name" -> Some `Read_name |> return         | other ->           error ~json:other "Expecting %S, %S or null (in \"sorting\": ...)"             "coordinate" "read-name"         end         >>= fun sorting ->         begin match kind with         | "single-end" -> return `SE         | "paired-end" -> return `PE         | other -> error "Kind in bam must be \"SE\" or \"PE\""         end         >>= fun kind ->         return (Of_bam (kind, sorting, refb, path))       | other ->         error ~json:other "Expecting string or null (in \"fragment\": ...)"     in     let fragment_of_yojson =       function       | `Assoc ["fragment-id", frag; "data", data] ->         begin match frag with         | `String s -> return (Some s)         | `Null -> return (None)         | other ->           error ~json:other "Expecting string or null (in \"fragment\": ...)"         end         >>= fun fragment_id ->         data_of_yojson data         >>= fun data_parsed ->         return (fragment_id, data_parsed)       | other -> error ~json:other "Expecting {\"fragment\": ... , \"data\": ...}"     in     match j with     | `Assoc [vtag, more] when vtag = current_version_tag ->       begin match more with       | `Assoc ["fastq",                 `Assoc ["sample-name"`String sample; "fragments"`List frgs]] ->         List.fold ~init:(return []) frgs ~f:(fun prev frag ->             prev >>= fun p ->             fragment_of_yojson frag             >>= fun more ->             return (more :: p))         >>= fun l ->         return (Fastq { fastq_sample_name = sample; files = List.rev l })       | `Assoc ["bam", bam] ->         begin match bam_of_yojson bam with         | Result.Ok ok -> return ok         | Result.Error err -> fail err         end         >>= fun bam ->         return (Bam bam)       | other ->         error ~json:other "Expecting Fastq or Bam"       end     | other ->       error ~json:other "Expecting Biokepi_input_v0"