summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2015-01-17 23:43:41 +0100
committerLudovic Courtès <ludo@gnu.org>2015-01-17 23:45:48 +0100
commit561fb6c31fbbc9ae91bc2ce338cefc841b284644 (patch)
tree0c8ecb82b7d58daabab6ae132a32dbb4c258bec6
parent4e190c2803be09ea7d500087cb1a2e3efeb27ab5 (diff)
downloadguix-561fb6c31fbbc9ae91bc2ce338cefc841b284644.tar.gz
doc: Document '%state-monad' and update '%store-monad' description.
* doc/guix.texi (The Store Monad): Document '%state-monad' and related
  procedures.  Describe '%store-monad' as an alias for '%state-monad'.
* guix/monads.scm: Update commentary.
-rw-r--r--doc/guix.texi64
-rw-r--r--guix/monads.scm2
2 files changed, 60 insertions, 6 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 50388c5809..857653dca4 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -2148,7 +2148,7 @@ provides a framework for working with @dfn{monads}, and a particularly
 useful monad for our uses, the @dfn{store monad}.  Monads are a
 construct that allows two things: associating ``context'' with values
 (in our case, the context is the store), and building sequences of
-computations (here computations includes accesses to the store.)  Values
+computations (here computations include accesses to the store.)  Values
 in a monad---values that carry this additional context---are called
 @dfn{monadic values}; procedures that return such values are called
 @dfn{monadic procedures}.
@@ -2257,14 +2257,68 @@ monadic expressions are ignored.  In that sense, it is analogous to
 @code{begin}, but applied to monadic expressions.
 @end deffn
 
+@cindex state monad
+The @code{(guix monads)} module provides the @dfn{state monad}, which
+allows an additional value---the state---to be @emph{threaded} through
+monadic procedure calls.
+
+@defvr {Scheme Variable} %state-monad
+The state monad.  Procedures in the state monad can access and change
+the state that is threaded.
+
+Consider the example below.  The @code{square} procedure returns a value
+in the state monad.  It returns the square of its argument, but also
+increments the current state value:
+
+@example
+(define (square x)
+  (mlet %state-monad ((count (current-state)))
+    (mbegin %state-monad
+      (set-current-state (+ 1 count))
+      (return (* x x)))))
+
+(run-with-state (sequence %state-monad (map square (iota 3))) 0)
+@result{} (0 1 4)
+@result{} 3
+@end example
+
+When ``run'' through @var{%state-monad}, we obtain that additional state
+value, which is the number of @code{square} calls.
+@end defvr
+
+@deffn {Monadic Procedure} current-state
+Return the current state as a monadic value.
+@end deffn
+
+@deffn {Monadic Procedure} set-current-state @var{value}
+Set the current state to @var{value} and return the previous state as a
+monadic value.
+@end deffn
+
+@deffn {Monadic Procedure} state-push @var{value}
+Push @var{value} to the current state, which is assumed to be a list,
+and return the previous state as a monadic value.
+@end deffn
+
+@deffn {Monadic Procedure} state-pop
+Pop a value from the current state and return it as a monadic value.
+The state is assumed to be a list.
+@end deffn
+
+@deffn {Scheme Procedure} run-with-state @var{mval} [@var{state}]
+Run monadic value @var{mval} starting with @var{state} as the initial
+state.  Return two values: the resulting value, and the resulting state.
+@end deffn
+
 The main interface to the store monad, provided by the @code{(guix
 store)} module, is as follows.
 
 @defvr {Scheme Variable} %store-monad
-The store monad.  Values in the store monad encapsulate accesses to the
-store.  When its effect is needed, a value of the store monad must be
-``evaluated'' by passing it to the @code{run-with-store} procedure (see
-below.)
+The store monad---an alias for @var{%state-monad}.
+
+Values in the store monad encapsulate accesses to the store.  When its
+effect is needed, a value of the store monad must be ``evaluated'' by
+passing it to the @code{run-with-store} procedure (see below.)
 @end defvr
 
 @deffn {Scheme Procedure} run-with-store @var{store} @var{mval} [#:guile-for-build] [#:system (%current-system)]
diff --git a/guix/monads.scm b/guix/monads.scm
index 62397dae7c..5bb860aadd 100644
--- a/guix/monads.scm
+++ b/guix/monads.scm
@@ -60,7 +60,7 @@
 ;;; Commentary:
 ;;;
 ;;; This module implements the general mechanism of monads, and provides in
-;;; particular an instance of the "store" monad.  The API was inspired by that
+;;; particular an instance of the "state" monad.  The API was inspired by that
 ;;; of Racket's "better-monads" module (see
 ;;; <http://planet.racket-lang.org/package-source/toups/functional.plt/1/1/planet-docs/better-monads-guide/index.html>).
 ;;; The implementation and use case were influenced by Oleg Kysielov's