Skip to content

Instantly share code, notes, and snippets.

@aboekhoff
Created June 23, 2010 23:10
Show Gist options
  • Save aboekhoff/450703 to your computer and use it in GitHub Desktop.
Save aboekhoff/450703 to your computer and use it in GitHub Desktop.
(ns combinatrix.sequence
(:require [combinatrix.core :as combinatrix]))
(combinatrix/defmonad
:name :sequence
:do in-sequence
:bind (fn [mv f] (mapcat (fn [x] (f x)) mv))
:return list
:zero ()
:plus concat)
(defn simple-sequence []
(in-sequence
x <- (range 3)
y <- (range 7 11)
:when (even? y)
(return [x y])))
(comment
(simple-sequence)
=> ([0 8] [0 10] [1 8] [1 10] [2 8] [2 10])
(sum (simple-sequence))
=> (0 8 0 10 1 8 1 10 2 8 2 10))
;;;;
(ns combinatrix.state
(:require [combinatrix.core :as combinatrix]))
(combinatrix/defmonad
:name :state
:do statefully
:bind (fn [mv f]
(fn [s]
(let [[v s*] (mv s)]
((f v) s*))))
:return (fn [v] (fn [s] [v s])))
(def get-state (fn [s] [s s]))
(defn set-state [n] (fn [s] [nil n]))
(def simply-stateful
(statefully
a <- get-state
(set-state "frobnicate")
b <- get-state
(set-state "grues!")
(return {:before a :after b})))
(comment
(simply-stateful 42)
=> [{:before 42 :after "frobnicate"} "grues!"])
;;;; a few generic fns magically loaded via load-file
;;;; that depend on functions bound to 'bind, 'return, 'zero and 'plus
(defn >> [mv mf] (bind mv (fn [])))
(defn fmap
[f mv]
(bind mv (fn [x] (return (f x)))))
(defn m-seq
[& mvs]
(letfn [(bind* [xs acc]
(if-let [[y & ys] (seq xs)]
(bind y (fn [z] (bind* ys (conj acc z))))
(return acc)))]
(bind* mvs [])))
(defn sum
([] zero)
([mvs] (sum zero mvs))
([init mvs] (reduce plus init mvs)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment