guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

The store monad


From: Ludovic Courtès
Subject: The store monad
Date: Tue, 01 Oct 2013 23:49:54 +0200
User-agent: Gnus/5.130007 (Ma Gnus v0.7) Emacs/24.3 (gnu/linux)

Hi!

I just pushed the ‘wip-monad’ branch for review (like we do in Guile,
‘wip-’ means that I may rebase it until it’s complete.)

So far in Guix we had two things: store primitives from (guix store)
that explicitly manipulate the store via effectful RPCs, and package
definitions, which are abstract, inert, and never see a store object.

Package objects are great, but they’re not necessarily suitable for
small derivations like the many we have in (gnu system …) modules.  Yet,
it would be nicer if functions in those modules did not have to
explicitly carry a ‘store’ parameter, and if the sequence of store
operations could be built and hidden under the carpet.

This is where monads come in.  In addition to being fashionable in FP
circles ;-), they offer a nice way to do exactly that: to add context to
values (here, the context is the store), and to build sequences of
computations.

So now, instead of writing procedures that explicitly manipulate the
store:

  (define (foo store)
    (let* ((drv (package-derivation store bash))
           (out (derivation->output-path drv)))
      (add-text-to-store store "foo.sh" (format #f "#!~a/bin/sh
echo hello world" out))))

  ;; Call the function:
  (foo (open-connection))

we can now write a monadic function:

  (define (foo)
    (mlet the-store-monad ((sh (package-file bash "bin/sh")))
      (text-file "foo.sh"
                 (string-append "#!" sh "\necho hello world"))))

  ;; Call the monadic function, and “run” its monadic result:
  ((foo) (open-connection))

Notice how ‘store’ completely disappeared.  Here we use ‘mlet’, not
‘let’, because ‘package-file’ returns a “monadic value” instead of a
normal value.

Monadic values in the store monad are currently just (lambda (store) …).

That’s the first time I use monads after just reading about it.  This
was mostly inspired by
<http://okmij.org/ftp/Scheme/monad-in-Scheme.html> and
<http://planet.racket-lang.org/package-source/toups/functional.plt/1/1/planet-docs/better-monads-guide/index.html>.
A good introduction is at <http://learnyouahaskell.com/a-fistful-of-monads>.

Actually, values in the Nix programming language essentially live in the
store monad, even if that’s not what it’s called.

I plan to polish it, add tests, and merge it in the coming days or so.

Comments welcome!

Thanks,
Ludo’.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]