package ogre

  1. Overview
  2. Docs

Monadic interface to the document.

This interface exposes actual setters and getters, that should be used to query data or to store it in a document. The interface is provided by a monad transformer functor, that wraps the Ogre monad into an arbitrary user monad.

Underneath the hood, the Ogre monad is a state monad wrapped into an error monad. The state holds the document, so that it is not needed to pass it along all the functions, and the error monad facilitates error propagation. We do not expose the catch function from the standard Error monad interface, as we are concerned that it will be abused (we don't see any legitimate usage of this function in the use cases of Ogre that we perceive).

The interface is built around 3 accessors functions for data querying and one mutator for inserting data into a document.

Data querying

In our model, a document is a set of facts, that describe some abstract entity. We're making a deriviations based on facts. To make a deriviation we need some facts, the particular set of required facts, as well as the modality of the requirement (i.e., how much it is needed), depends on the particular deriviation. For example, we might require a fact to be present or, if it is optional, we might request it, finally, we may query for a collection of facts, and apply our deriviation foreach fact. In other terms, require attribute mandates that there is one and only one value of the given attribute, request attribute asks for zero or one value, and foreach attribute requires zero or more values of the attribute.

include Monads.Std.Monad.S
type 'a t
val void : 'a t -> unit t

void m computes m and discrards the result.

val sequence : unit t list -> unit t

sequence xs computes a sequence of computations xs in the left to right order.

val forever : 'a t -> 'b t

forever xs creates a computationt that never returns.

module Fn : sig ... end

Various function combinators lifted into the Kleisli category.

module Pair : sig ... end

The pair interface lifted into the monad.

module Triple : sig ... end

The triple interface lifted into a monad.

module Lift : sig ... end

Lifts functions into the monad.

module Exn : sig ... end

Interacting between monads and language exceptions

module Collection : sig ... end

Lifts collection interface into the monad.

module List : Collection.S with type 'a t := 'a list

The Monad.Collection.S interface for lists

module Seq : Collection.S with type 'a t := 'a Core_kernel.Sequence.t

The Monad.Collection.S interface for sequences

include Monads.Std.Monad.Syntax.S with type 'a t := 'a t
val (>=>) : ('a -> 'b t) -> ('b -> 'c t) -> 'a -> 'c t

f >=> g is fun x -> f x >>= g

val (!!) : 'a -> 'a t

!!x is return x

val (!$) : ('a -> 'b) -> 'a t -> 'b t

!$f is Lift.unary f

val (!$$) : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t

!$$f is Lift.binary f

val (!$$$) : ('a -> 'b -> 'c -> 'd) -> 'a t -> 'b t -> 'c t -> 'd t

!$$$f is Lift.ternary f

val (!$$$$) : ('a -> 'b -> 'c -> 'd -> 'e) -> 'a t -> 'b t -> 'c t -> 'd t -> 'e t

!$$$$f is Lift.quaternary f

val (!$$$$$) : ('a -> 'b -> 'c -> 'd -> 'e -> 'f) -> 'a t -> 'b t -> 'c t -> 'd t -> 'e t -> 'f t

!$$$$$f is Lift.quinary f

include Monads.Std.Monad.Syntax.Let.S with type 'a t := 'a t
val let* : 'a t -> ('a -> 'b t) -> 'b t

let* r = f x in b is f x >>= fun r -> b

val and* : 'a t -> 'b t -> ('a * 'b) t

monoidal product

val let+ : 'a t -> ('a -> 'b) -> 'b t

let+ r = f x in b is f x >>| fun r -> b

val and+ : 'a t -> 'b t -> ('a * 'b) t

monoidal product

include Core_kernel.Monad.S with type 'a t := 'a t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t

t >>= f returns a computation that sequences the computations represented by two monad elements. The resulting computation first does t to yield a value v, and then runs the computation returned by f v.

val (>>|) : 'a t -> ('a -> 'b) -> 'b t

t >>| f is t >>= (fun a -> return (f a)).

module Monad_infix : sig ... end
val bind : 'a t -> f:('a -> 'b t) -> 'b t

bind t ~f = t >>= f

val return : 'a -> 'a t

return v returns the (trivial) computation that returns v.

val map : 'a t -> f:('a -> 'b) -> 'b t

map t ~f is t >>| f.

val join : 'a t t -> 'a t

join t is t >>= (fun t' -> t').

val ignore_m : 'a t -> unit t

ignore_m t is map t ~f:(fun _ -> ()). ignore_m used to be called ignore, but we decided that was a bad name, because it shadowed the widely used Caml.ignore. Some monads still do let ignore = ignore_m for historical reasons.

val all : 'a t list -> 'a list t
val all_unit : unit t list -> unit t

Like all, but ensures that every monadic value in the list produces a unit value, all of which are discarded rather than being collected into a list.

module Let_syntax : sig ... end

These are convenient to have in scope when programming with a monad:

module Let : Monads.Std.Monad.Syntax.Let.S with type 'a t := 'a t

Monadic operators, see Monad.Syntax.S for more.

module Syntax : Monads.Std.Monad.Syntax.S with type 'a t := 'a t

Monadic operators, see Monad.Syntax.S for more.

include Monads.Std.Monad.Trans.S with type 'a t := 'a t
type 'a m
type 'a e
val lift : 'a m -> 'a t

lifts inner monad into the resulting monad

val require : ?that:('a -> bool) -> ('a, _) attribute -> 'a t

require a ~that:p requires that an attribute a has one and only one value that satisfies a predicate p. It is an error, if there are no such values, or if there are more than one value.

val request : ?that:('a -> bool) -> ('a, _) attribute -> 'a option t

request a ~that:p request no more than one value of an attribute a, that satisfies a predicate p. The returned value is wrapped in an option. If there are more than one satisfying value, then it is an error.

val foreach : ('a -> 'b) query -> f:'a -> 'b seq t

foreach query ~f:action applies an action for each value of an attributes specified in the query. The query value is built using a domain specific language embedded into OCaml. This language is very similar to SQL, and has join and where clauses, e.g.,

let better_than_average_students =
  foreach Query.(begin
        ~where:(students.(gpa) > float 3.5)
          [field classid];
            field teacher ~from:students;
            field id ~from:teachers
        (from students $ teachers)
    ~f:(fun s t -> return (s,t))

The type of the query value encodes the type of the function f. A well formed query has a type of form (t1 -> t2 -> .. -> tm -> 'a t) -> 'a t, where t1 till tm are types of attributes enumerated in the from clause (in that particular order).

See the Query module documentation for more information about the query EDSL.

val collect : (('a -> 'a) -> 'b) query -> 'b seq t

collect query is the same as foreach query

val provide : (_, 'a -> unit t) attribute -> 'a

provide attr v1 v2 ... vm stores the constituents of an attribute value in the document. An attribute type encodes not only the type of an attribute value, but also a type and the order of the fields. Thus, the attribute itself captures a format of the attribute representation, the same as format is used in printf-like functions. In that sense, the provide function is variadic, where the first argument (the attribute) defines the type and the arity of the function.

val fail : Core_kernel.Error.t -> 'a t

fail error aborts an inference process with the specified error.

val failf : ('a, Format.formatter, unit, unit -> 'b t) Core_kernel.format4 -> 'a

failf fmt args... () constructs an error based on the specified format fmt and arguments, terminated by the unit value (). Example:

failf "the file type %s is unsupported" name ()

Note: don't forget to terminate a sequence of arguments with an extra unit value. See the corresponding invalid_argf and failwithf function for the reason, why this extra argument is needed.

val eval : 'a t -> doc -> 'a Core_kernel.Or_error.t m

eval property document makes an inference of a property based on facts stored in a document. If all requirements are satisfied and no errors occurred the inferred result.

For example, given the property names_of_best_students, defined as,

let names_of_best_students =
  foreach Query.(select (from students)
                   ~where:(students.(gpa) > float 3.8))
    ~f:(fun s -> return ( s))

we can evaluate this property, with

eval names_of_best_students

to get a sequence (possibly empty) of all students that have the GPA score greater than 3.8.

val exec : 'a t -> doc -> doc Core_kernel.Or_error.t m

exec op doc executes an operation op that, presumably, updates the document doc, returns an updated version.

val run : 'a t -> doc -> ('a * doc) Core_kernel.Or_error.t m

run op doc runs an operation op that does some inference as well as may update the document. This function is a usual part of a generic state monad interface, and is provided for the consistency. Usually, it is a bad idea, or a notion of a bad style to use this function.