Created
October 1, 2012 14:56
-
-
Save takikawa/3812284 to your computer and use it in GitHub Desktop.
monads with generics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; using the idea from this blog post: http://www.clojure.net/2012/06/03/Monad-Protocols/ | |
#lang racket | |
(require (for-syntax syntax/parse)) | |
(module monad racket | |
(require racket/generic) | |
(define (vector-mapcat f v) | |
(apply vector-append | |
(for/list ([elem (vector-map f v)]) | |
(if (vector? elem) | |
elem | |
(vector elem))))) | |
(define-generics monad | |
(do-result monad v) | |
(bind monad f)) | |
(define (-do-result m v) | |
(cond [(vector? m) (vector v)] | |
[else (do-result m v)])) | |
(define (-bind m v) | |
(cond [(vector? m) (vector-mapcat v m)] | |
[else (bind m v)])) | |
(provide gen:monad | |
monad? | |
(rename-out | |
[-bind bind] | |
[-do-result do-result]))) | |
(require 'monad) | |
(define-syntax (do stx) | |
(define-syntax-class binding | |
(pattern (x:id <- val:expr))) | |
(syntax-parse stx | |
[(_ b:binding b1:binding ...+ e:expr) | |
#'(bind b.val (λ (b.x) (do b1 ... e)))] | |
[(_ b:binding e:expr) | |
#'(bind b.val (λ (b.x) (do-result b.val e)))])) | |
(bind #(1 2 4) add1) | |
(do [x <- #(1 2 3)] | |
[y <- #(10 11)] | |
(+ x y)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment