# Structuring FRP (specifically Note) applications

**URL:** <https://discuss.ocaml.org/t/structuring-frp-specifically-note-applications/8645>\
**Category:** Learning\
**Tags:** javascript, jsoo\
**Created:** [October 18, 2021, 11:24am UTC](https://discuss.ocaml.org/t/structuring-frp-specifically-note-applications/8645 "2021-10-18T11:24:33Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![Chimrod](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chimrod/32/6042_2.png) [@Chimrod](https://discuss.ocaml.org/u/Chimrod)\
**Post date:** [October 18, 2021, 3:05pm UTC](https://discuss.ocaml.org/t/structuring-frp-specifically-note-applications/8645/2 "2021-10-18T15:05:30Z")

</div>

I think that your state should include a status telling if you are `Loading` or `Running` the application :

```ocaml
type t =
  { status : [`Loading | `Running]
  ; data : …
  }

```

As long as you do not store functionnal values inside the state, you can add as many elements as you want (if you want to add such elements in the state, you have to provide your own `compare` function in order to avoid error in runtime).

Then, here is how I run my event loop: each event is handled inside it’s own module and I avoid the monolithic pattern matching:

```ocaml
(** The Make module build the main application loop.

    The function [run] update the state on each event, and return a new state.
    Each event must follow the [event] type, which is composed from the type
    [t], and a module with a fonction [update].

    This example create an application with the state containing a simple
    counter. An even which increment this counter is created and can be used to
    update the state.

    [
        type state = { value : int }

        (** Increment the state. *)
        module Incr = struct
            type t = unit

            let update () state = { value = state.value + 1 }
        end

        (** Decrement the state. *)
        module Incr = struct
            type t = unit

            let update () state = { value = state.value - 1 }
        end

        module App = Make(struct type t = state end)

        (* Create the events *)
        let incr_event = App.E ((), (module Incr:App.Event with type t = Incr.t))
        let decr_event = App.E ((), (module Decr:App.Event with type t = Decr.t))

        let init = { value = 0 } in

        (* Run the main loop *)
        let state = App.run
          init
          (E.select
            [ incr_event
            ; decr_event ] ) in …
    ]

*)
module Make(S:sig type t end) = struct
  module type Event = sig

    type t

    val update: t -> S.t -> S.t

  end

  type event = E : 'a * (module Event with type t = 'a) -> event

  (** Simple helper for the main event loop *)
  let run
    : ?eq:(S.t -> S.t -> bool) -> S.t -> event Note.E.t -> S.t Note.S.t
    = fun ?eq init event ->
      let action = Note.E.map (fun (E (t, (module Event))) st -> Event.update t st) event in
      Note.S.accum ?eq init action
end

```

I have applied this pattern in differents applications, and this works fine. I’ve found the inspiration in this post : [The shape design problem - #26 by kantian](https://discuss.ocaml.org/t/the-shape-design-problem/7810/26)

Hope this helps 🙂

---

_[View the full topic](https://discuss.ocaml.org/t/structuring-frp-specifically-note-applications/8645)._
