Skip to content

Instantly share code, notes, and snippets.

@mgreenly
Created May 4, 2014 15:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgreenly/07649b97e519b8543163 to your computer and use it in GitHub Desktop.
Save mgreenly/07649b97e519b8543163 to your computer and use it in GitHub Desktop.
; monads
;
; references:
; http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/
; http://www.intensivesystems.net/tutorials/monads_101.html
; http://en.wikipedia.org/wiki/Monad_(functional_programming)
;
(define-method return (monad)
(make monad :value))
(define-method return (monad value)
(make monad :value value))
;
; define the 'nothing' monad
;
(define-class <nothing> () ())
(define-method value-of ((monad <nothing>)) :nothing)
(define-method bind ((monad <nothing>) function) monad)
;
; define the 'maybe' monad
;
(define-class <maybe> ()
((value :init-keyword :value :accessor value-of)))
(define-method bind (monad function)
(let ((result (function (value-of monad))))
(if (is-a? result <nothing>)
result
(return <maybe> result))))
;
; define a few functions to use on the monadic values
;
(define (f v) (* v v)) ; square the value
(define (g v) (+ v v)) ; double the value
(define (h v)
(if (> v 10)
(return <nothing>)
(- v 1)))
(value-of (bind (bind (bind (return <maybe> 4) f ) h) g)) ; -> :nothing (g (h (f 4)))
(value-of (bind (bind (bind (return <maybe> 4) g ) h) f)) ; -> 49 (f (h (g 4)))
; notice that the functions f and g don't know anything about <nothing> and
; they still don't blow up when those functions are chained together
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment