Module quasi-object syntax

I have been fooling around with what I believe are “first class” modules, and have a syntax problem - there is no way, am I right?

From here
type x = { a: (module Gesture) }

let v = { a = create_wave "hi" }

I can do this:
in let (module G: Gesture) = v.a in G.perform ()

… but no way to apply directly to the record field, without a “let binding”?
in v.a.perform ()

(rest of code for example follows:)

module type Gesture = sig
    type t
    val gesture : t
    val perform : unit -> unit
    end

let create_wave s =
    let module Wave: Gesture = struct
        type t = string
        let gesture = s
        let perform () = Printf.printf "Wave \"%s\"\n" gesture
        end
    in (module Wave : Gesture)

let create_finger i =
    let module Finger: Gesture = struct
        type t = int
        let gesture = i
        let perform () = Printf.printf "Finger %d\n" gesture
        end
    in (module Finger: Gesture)

If I understand correctly, no, you can’t just “apply directly to the record field”. I guess the reason for this is that type inference is often driven by syntax and in the case of v.a.perform it is understood that v.a should have record type (in the same way that v should have record type previously in v.a) since module names are capitalized.

If you are annoyed by writing the type explicitly in the let binding, you can also write:

  let v = { a = create_wave "hi" } in
  let module G = (val v.a) in
  G.perform ()

Hope it helps!

Disclaimer: I’m a beginner in the language, so take this with a grain of salt.