module type T = sig ... end
module type T_conv = sig ... end
module type T_pipe = sig ... end
type 'state t = [
  1. | `Plain of (module T with type state = 'state)
  2. | `Plain_conv of (module T_conv with type state = 'state)
  3. | `Pipe of (module T_pipe with type state = 'state)
val lift : 'a t -> f:('b -> 'a) -> 'b t

Given an RPC that expects a state type 'a, it can use a state type 'b if we tell it how to extract an 'a from it. Note that this extraction is done on every RPC call, so should be cheap and should not copy mutable state that you want to persist across calls.