A cheap and cheerful MVC library for writing interactive web pages with Ocaml that are compiled into Javascript with js_of_ocaml.
Warning: everything will change.
The library (such as it is) is based around a single Component
module signature:
module type Component = sig
type state
type action
val render : state -> action html
val update : action -> state -> state
val initial : state
end
The type state
represents the set of all possible states that the
component can be in, and the type action
represents all the possible
actions that can be peformed by the user. For each possible state, the
render
function generates a reactive HTML document that can be
manipulated by the use to generate actions. The update
function is
then used to translate an action into a state transformation
function. The initial
value is used as the initial state of the
component.
The functions render
and update
are intended to be purely
functional.
The HTML tree generated by the render
function is translated into
DOM nodes using an algorithm similar to (but as yet less sophisticated
than) the one used by
React.js. This ensures
that OCamlMVC can maintain the illusion of writing a whole new HTML
tree to the interface on every state update, while remaining
reasonably efficient.
There is one demo at the moment: a very simple todo list application, with undo/redo capability added by a generic “VCR” functor. A compiled version of the demo can be seen on my website.
This application is constructed in layers:
-
There is a pure OCaml core (i.e., with no Javascript-specific stuff), implemented in the module
TodoList
. -
The todo list data structure is then used as the ‘model’ for an OCamlMVC
Component
as described above. This is implemented in theTodoListComponent
module, and primarily consists of code to render the state of a todo list as an HTML tree (using the combinators provded by theOCamlMVC.HTML
module), and to route the actions generated by user interaction back to the model. -
The Undo/Redo functionality is then added by using the
VCR.Of
functor that mapsComponent
s toComponent
s, adding a history and a future to the state of the underlying component, and augmenting the UI with “Undo” and “Redo” buttons. -
The
Main
module then attaches the composed component to a specified element in the DOM.
The styling is provided by the Zurb Foundation CSS framework.
I think this will work: