Skip to content

Instantly share code, notes, and snippets.

@hugoduncan
Created March 1, 2011 05:01
Show Gist options
  • Save hugoduncan/848641 to your computer and use it in GitHub Desktop.
Save hugoduncan/848641 to your computer and use it in GitHub Desktop.
Crate monad
(ns pallet.crate
"The crate monad.
There are two issues with crates as monads.
i) need to reimplement crate functions to return functions of one
argument [state], so that they have a common signature for manipulation
as monadic functions.
ii) to achieve pluggable error handling, etc, via monads, requires
runtime use of monads, which isn't possible with c.c.monads."
(:require
[clojure.contrib.monads :as monad]))
(def ^{:doc "The crate monad is an identity monad"}
crate-m monad/identity-m)
(defmacro cratefn
"Create an anonymous crate function"
[[request & args] & body]
`(fn [~@args] (fn [~'request] ~@body)))
(def a (cratefn [request a] (assoc request :a a)))
(def bc (cratefn [request b c] (assoc request :b b :c c)))
(use 'clojure.test)
(deftest cratefn-test
(is (= {:a 1} ((a 1) {:a 2})))
(is (= {:a 1 :b 2 :c 3} ((bc 2 3) {:a 1}))))
(deftest basic-test
(is (= {:a 1} (monad/with-monad crate-m (m-bind {:a 1} identity))))
(is (= {:a 1 :b 2}
(monad/with-monad crate-m
((monad/m-chain [ #(assoc % :a 1) #(assoc % :b 2)]) {}))))
(is (= {:a 1 :b 2 :c 3}
(monad/with-monad crate-m
((monad/m-chain [(a 1) (bc 2 3)]) {}))))
(is (= {:a 1 :b 2 :c 3}
(monad/with-monad crate-m
((monad/m-chain [(a 4) (bc 2 3) (a 1)]) {})))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment