Last active
August 29, 2015 14:26
-
-
Save gatlin/6b4253a75df1acf866f9 to your computer and use it in GitHub Desktop.
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
#lang racket | |
; We begin with the S and K combinators | |
(define S (λ (x) | |
(λ (y) | |
(λ (z) | |
((x z) (y z)))))) | |
(define K (λ (x) (λ (y) x))) | |
; The I combinator falls out pretty easily from these two, giving an identity function | |
(define I ((S K) K)) ; (I 2) => 2 | |
; Function composition is also easily defined with these combinators | |
(define compose ((S (K S)) K)) | |
; reverse function application, which we will use momentarily | |
(define app ((S (K (S I))) K)) ; (app x f) => (f x) | |
; We have everything we need to define the monad over unary functions | |
; (in Haskell it's called the `Reader` monad). | |
; This monad allows computations to thread a read-only state value through | |
; composition of functions. | |
(define return K) | |
(define join (S app)) | |
(define (>>= ma f) (join ((compose f) ma))) | |
; `ask` is how a computation may access the state value. | |
(define ask I) | |
; `local` may be used to modify the state value locally for a sub-computation, though | |
; it will be reverted when the sub-computation terminates. | |
(define (local f m) ((compose m) f)) | |
(define r1 | |
(ask . >>= . (λ (n) | |
(return (eq? (modulo n 2) 0))))) | |
(define r2 (λ (is-even?) | |
(ask . >>= . (λ (n) | |
(let ([s (number->string n)]) | |
(if is-even? | |
(return (string-append s " is even!")) | |
(return (string-append s " is odd!")))))))) | |
(define r3 (r1 . >>= . r2)) | |
(define plus-1 (λ (x) (+ 1 x))) | |
(define r4 | |
(ask . >>= . (λ (n) | |
(local plus-1 r1)))) | |
(define r5 (r4 . >>= . r2)) | |
; (r1 10) => #t | |
; (r3 10) => "10 is even!" | |
; (r5 10) => "10 is odd!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment