struct

  type t =
    | Set of Key_in_collection.t * string
    | Unset of Key_in_collection.t
    | Sequence of t list
    | Check of Key_in_collection.t * string option
  let _key ?collection key = {Key_in_collection. key; collection}
  let set ?collection ~key value = Set (_key ?collection key, value)
  let seq l = Sequence l
  let contains ?collection ~key v = Check (_key ?collection key, Some v)
  let is_not_set ?collection key = Check (_key ?collection key, None)
  let unset ?collection key = Unset (_key ?collection key)
  let rec to_string (t: t) =
    match t with
    | Set (k, v) -> sprintf "(set %s %S)" (Key_in_collection.to_string k) v
    | Unset k -> sprintf "(unset %s)" (Key_in_collection.to_string k)
    | Sequence l -> sprintf "(sequence %s)" (List.map l ~f:to_string
                                             |> StringLabels.concat ~sep:" ")
    | Check (k, v) ->
      sprintf "(check %s %s)" (Key_in_collection.to_string k)
        (Option.value_map ~default:"None" v ~f:(sprintf "(Some %S)"))

end