Changeset 26985 in project


Ignore:
Timestamp:
07/05/12 04:47:03 (9 years ago)
Author:
svnwiki
Message:

Anonymous wiki edit for IP [70.71.183.40]: Updates the Monad docs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wiki/eggref/4/monad

    r26566 r26985  
    4141Yes, sometimes this isn't strictly a necessary set of functionality. But for when it is, save yourself some time and write a monad.
    4242
    43 === What's this about lazy evaluation?
    44 
    45 Yes, this monad implementation is lazily evaluated.
    46 
    47 
    4843=== Functions
    4944
    50 ==== (define-monad name unit-function bind-function)
     45==== (define-monad name unit-function bind-function [fail-function])
    5146
    5247<procedure>(define-monad name unit-function bind-function [fail-function])</procedure>
     
    7368<tr><td>&gt;&gt;=</td><td>Maps to bind</td></tr>
    7469<tr><td>return</td><td>Maps to unit</td></tr>
     70<tr><td>fail</td><td>Maps to fail</td></tr>
    7571</table>
    7672
     
    133129Similar to the (using) procedure, but allows for even more terseness.
    134130
    135 Within the (do-using) body a special binding syntax is allowed, which can be understood by this example:
     131Within do-using the following will be defined:
     132
     133<table>
     134<tr><th>Function</th><th>Usage</th></tr>
     135<tr><td>&gt;&gt;=</td><td>Maps to bind</td></tr>
     136<tr><td>return</td><td>Maps to unit</td></tr>
     137<tr><td>fail</td><td>Maps to fail</td></tr>
     138<tr><td>/m</td><td>Shorthand for calling monad-specific functions, details follow</td></tr>
     139<tr><td>/m!</td><td>Shorthand for calling monad-specific functions, details follow</td></tr>
     140<tr><td>&lt;-</td><td>Shorthand for binding a symbol to a monadic value, details follow</td></tr>
     141</table>
     142
     143===== /m! Keyword
     144
     145The /m! keyword is used as a shortcut for referencing monad-specific procedures which are prefixed with the current monad name.
     146
     147For example:
     148
     149<enscript highlight="scheme">
     150(do-using <writer> (/m! tell 1))
     151</enscript>
     152
     153Is the same as:
     154
     155<enscript highlight="scheme">
     156(do-using <writer> (<writer>-tell 1))
     157</enscript>
     158
     159===== /m Keyword
     160
     161The /m keyword is like /m!, except that it references the procedure without executing it.
     162
     163For example:
     164
     165<enscript highlight="scheme">
     166(do-using <state> (x <- (/m get)) (return x))
     167</enscript>
     168
     169Is the same as:
     170
     171<enscript highlight="scheme">
     172(do-using <writer> (x <- <state>-get) (return x))
     173</enscript>
     174
     175===== <- Keyword
     176
     177The <- keyword is used as a shortcut for binding a value within a monad.
     178
     179For example:
     180
     181<enscript highlight="scheme">
     182(do-using <maybe>
     183  (x <- (return 1))
     184  x)
     185</enscript>
     186
     187Is the same as:
     188
     189<enscript highlight="scheme">
     190(do-using <maybe>
     191  (>>= (return 1)
     192    (lambda (x)
     193      (do-using <maybe>
     194        x))))
     195</enscript>
     196
     197===== General Example
     198
     199A simple example:
    136200
    137201<enscript highlight="scheme">
     
    139203   (x <- (return <maybe> 1))
    140204   x)
    141  
     205
    142206;Returns:
    143207(Just 1)
     
    148212<enscript highlight="scheme">
    149213(do-using <maybe>
    150           (x <- (return <maybe> 1))
     214          (x <- (return 1))
    151215          (if (eq? 2 (cadr x))
    152               (return <maybe> 'Banana)
    153               (fail <maybe>))
    154           (y <- (return <maybe> 'Apple))
     216              (return 'Banana)
     217              (fail))
     218          (y <- (return 'Apple))
    155219          y)
     220
    156221;Returns:
    157222Nothing
    158223</enscript>
    159224
     225==== (do monad [body ...])
     226
     227<procedure>(do monad [body ...])</procedure>
     228
     229Alias for (do-using monad [body ...]).
     230
    160231=== Basic Monads
    161232
     
    165236
    166237<enscript highlight="scheme">
    167  (define-monad
    168    <id>
    169    (lambda (a) a)
    170    (lambda (a f) (f a)))
     238(define-monad
     239  <id>
     240  (lambda (a) a)
     241  (lambda (a f) (f a)))
    171242</enscript>
    172243
     
    174245
    175246<enscript highlight="scheme">
    176   (define-monad
    177     <maybe>
    178     (lambda (a) a)
    179     (lambda (a f) (if a (f a) #f))
    180     (case-lambda (() 'Nothing)
    181                  ((_ . _) 'Nothing)))
     247(define-monad
     248  <maybe>
     249  (lambda (a) a)
     250  (lambda (a f) (if a (f a) #f))
     251  (case-lambda (() 'Nothing)
     252               ((_ . _) 'Nothing)))
     253</enscript>
     254
     255===== Example
     256
     257<enscript highlight="scheme">
     258> (do <maybe>
     259      (if #t
     260          'Nothing
     261          '(Just First))
     262      '(Just Second))
     263Nothing
    182264</enscript>
    183265
     
    185267
    186268<enscript highlight="scheme">
    187  (define-monad
    188    <list>
    189    (lambda (a) (list a))
    190    (lambda (a f) (concatenate! (map! f a))))
     269(define-monad
     270  <list>
     271  (lambda (a) (list a))
     272  (lambda (a f) (concatenate! (map! f a))))
     273</enscript>
     274
     275===== Example
     276
     277<enscript highlight="scheme">
     278#;> (do <list>
     279        (x <- '(1 2 3))
     280        (y <- '(a b c))
     281        (return `(,x ,y)))
     282((1 a) (1 b) (1 c) (2 a) (2 b) (2 c) (3 a) (3 b) (3 c))
    191283</enscript>
    192284
     
    194286
    195287<enscript highlight="scheme">
    196   (define-monad
    197     <state>
    198     (lambda (a) (lambda (s) `(,a . ,s)))
    199     (lambda (a f)
    200       (lambda (s)
    201         (let* ((p (a s))
    202                (a^ (car p))
    203                (s^ (cdr p)))
    204           ((f a^) s^)))))
     288(define-monad
     289  <state>
     290  (lambda (a) (lambda (s) `(,a . ,s)))
     291  (lambda (a f)
     292    (lambda (s)
     293      (let* ((p (a s))
     294             (a^ (car p))
     295             (s^ (cdr p)))
     296        ((f a^) s^)))))
     297</enscript>
     298
     299===== Extra Methods
     300
     301====== <state>-get
     302
     303<procedure>(<state>-get s)</procedure>
     304
     305Retrieves the current state from a given <state> monad.
     306
     307======= Example
     308
     309<enscript highlight="scheme">
     310#;> ((do <state>
     311         (x <- (/m get))
     312         (return x))
     313     "Hi!")
     314("Hi!" . "Hi!")
     315</enscript>
     316
     317====== <state>-gets
     318
     319<procedure>(<state>-gets f)</procedure>
     320
     321Creates a monad that retrieves a given state after filtering it with the function provided.
     322
     323======= Example
     324
     325<enscript highlight="scheme">
     326#;> ((do <state>
     327         (x <- (/m! gets (lambda (s) (+ s 1))))
     328         (return x))
     329     1)
     330(2 . 1)
     331</enscript>
     332
     333====== <state>-modify
     334
     335<procedure>(<state>-modify f)</procedure>
     336
     337Creates a monad that modifies the current state with a given function.
     338
     339======= Example
     340
     341<enscript highlight="scheme">
     342#;> ((do <state>
     343         (/m! modify (lambda (v)
     344                      (display (format "Received: ~S\n" v))
     345                      (+ v 1))))
     346     1)
     347Received: 1
     348(() . 2)
     349</enscript>
     350
     351====== <state>-put
     352
     353<procedure>(<state>-put v)</procedure>
     354
     355Creates a monad that forces a value into the current <state> monad.
     356
     357======= Example
     358
     359<enscript highlight="scheme">
     360#;> ((do <state>
     361         (/m! put 1))
     362     2)
     363(() . 1)
    205364</enscript>
    206365
     
    208367
    209368<enscript highlight="scheme">
    210   (define-monad
    211     <reader>
    212     (lambda (a) (lambda (v) a))
    213     (lambda (a f) (lambda (v) ((f (a v)) v))))
     369(define-monad
     370  <reader>
     371  (lambda (a) (lambda (v) a))
     372  (lambda (a f) (lambda (v) ((f (a v)) v))))
     373</enscript>
     374
     375===== Extra Methods
     376
     377====== <reader>-ask
     378
     379<procedure>(<reader>-ask m)</procedure>
     380
     381Extracts the current value from the current reader monad.
     382
     383======= Example
     384
     385<enscript highlight="scheme">
     386#;> ((do <reader>
     387         (x <- (/m ask))
     388         (return (+ x 1)))
     389     1)
     3902
     391</enscript>
     392
     393====== <reader>-asks
     394
     395<procedure>(<reader>-asks f)</procedure>
     396
     397Creates a monad that filters the current value in the reader monad with the given function.
     398
     399======= Example
     400
     401<enscript highlight="scheme">
     402#;> ((do <reader>
     403         (/m! asks (lambda (v)
     404                    (+ v 1))))
     405     1)
     4062
     407</enscript>
     408
     409====== <reader>-local
     410
     411<procedure>(<reader>-local f m)</procedure>
     412
     413Creats a monad that first filters the current reader monad value with the provided function, then passes that filtered value to the provided reader monad.
     414
     415======= Example
     416
     417<enscript highlight="scheme">
     418#;> ((do <reader>
     419         (/m! local
     420             (lambda (v) (+ v 1))
     421             (do <reader>
     422                 (x <- (/m ask))
     423                 (return x))))
     424     1)
     4252
    214426</enscript>
    215427
     
    217429
    218430<enscript highlight="scheme">
    219   (define-monad
    220     <cps>
    221     (lambda (a) (lambda (k) (k a)))
    222     (lambda (a f) (lambda (k) (a (lambda (a^) (let ((b (f a^))) (b k)))))))
    223 </enscript>
     431(define-monad
     432  <cps>
     433  (lambda (a) (lambda (k) (k a)))
     434  (lambda (a f) (lambda (k) (a (lambda (a^) (let ((b (f a^))) (b k)))))))
     435</enscript>
     436
     437===== Extra Methods
     438
     439====== <cps>-call/cc
     440
     441<procedure>(<cps>-call/cc f)</procedre>
     442
     443Creates a monad that, when given a continuation, passes a monad to the provided function that applies the continuation to its input; then applies the continuation to the output of that function.
    224444
    225445==== Exception
    226446
    227447<enscript highlight="scheme">
    228   (define-monad
    229     <exception>
    230     (lambda (a) `(success ,a))
    231     (lambda (a f) (if (eq? (car a) 'success) (f (cadr a)) a))
    232     (case-lambda (() `(failure))
    233                  ((a . b) `(failure ,a . ,b))))
     448(define-monad
     449  <exception>
     450  (lambda (a) `(success ,a))
     451  (lambda (a f) (if (eq? (car a) 'success) (f (cadr a)) a))
     452  (case-lambda (() `(failure))
     453               ((a . b) `(failure ,a . ,b))))
     454</enscript>
     455
     456===== Extra Methods
     457
     458====== <exception>-throw
     459
     460<procedure>(<exception-throw e)</procedure>
     461
     462Synonym for <exception>-fail.
     463
     464======= Example
     465
     466<enscript highlight="scheme">
     467#;> (do <exception> (/m! throw "Error! No more cheerios!"))
     468(failure "Error! No more cheerios!")
     469</enscript>
     470
     471====== <exception>-catch
     472
     473<procedure>(<exception>-catch m f)</procedure>
     474
     475Creates a monad that examines an exception monad and passes the value to the provided function if it had failed.
     476
     477======= Example
     478
     479<enscript highlight="scheme">
     480#;> (define some-monad
     481            (do <exception>
     482                (/m! throw "An error happened! Oh no!")))
     483#;> (do <exception>
     484        (/m! catch some-monad
     485                  (lambda (m)
     486                    (display (format "Caught an exception: ~S"
     487                                     (cadr m))))))
     488Caught an exception: "An error happened! Oh no!"
    234489</enscript>
    235490
     
    237492
    238493<enscript highlight="scheme">
    239   (define-monad
    240     <writer>
    241     (lambda (a) `(,a . ()))
    242     (lambda (a f)
    243       (let ((b (f (car a))))
    244         `(,(car b) . ,(append (cdr a) (cdr b))))))
     494(define-monad
     495  <writer>
     496  (lambda (a) `(,a . ()))
     497  (lambda (a f)
     498    (let ((b (f (car a))))
     499      `(,(car b) . ,(append (cdr a) (cdr b))))))
     500</enscript>
     501
     502===== Extra Methods
     503
     504====== <writer>-tell
     505
     506<procedure>(<writer>-tell v)</procedure>
     507
     508Creates a monad where the provided value is wrapped in a <writer>.
     509
     510======= Example
     511
     512<enscript highlight="scheme">
     513#;> (do <writer> (/m! tell '(1 2 3)))
     514(() 1 2 3)
     515</enscript>
     516
     517====== <writer>-listen
     518
     519<procedure>(<writer>-listen a)</procedure>
     520
     521Creates a monad where the value has been extracted out of the writer.
     522
     523======= Example
     524
     525<enscript highlight="scheme">
     526#;> (do <writer>
     527        (x <- (/m! listen
     528                  (/m! tell '(foo))))
     529        (return x))
     530((() foo) foo)
     531</enscript>
     532
     533====== <writer>-listens
     534
     535<procedure>(<writer>-listens f m)</procedure>
     536
     537Creates a monad that is the outcome of applying the provided function on the given writer monad.
     538
     539======= Example
     540
     541<enscript highlight="scheme">
     542#;> (do <writer>
     543        (x <- (return (/m! tell '(1 2 3))))
     544        (/m! listens
     545            (lambda (l) (map (lambda (v) (+ v 1)) l))
     546            (return x)))
     547((() 2 3 4))
     548</enscript>
     549
     550====== <writer>-pass
     551
     552<procedure>(<writer>-pass m)</procedure>
     553
     554Creates a monad that is the outcome of mutating the provided writer monad with a given function. Expects to be provided a monad of the form: ((value . function) . rest-of-writer)
     555
     556Not generally used much except by those that know what they're doing, you're likely after <writer>-censor for most cases.
     557
     558======= Example
     559
     560<enscript highlight="scheme">
     561#;> (do <writer>
     562        (x <- (/m! listen
     563                  `((() . ,(lambda (l)
     564                             (map (lambda (v) (+ v 1)) l)))
     565                    . (1 2 3))))
     566        (/m! pass x))
     567(() 1 2 3 2 3 4)
     568</enscript>
     569
     570====== <writer>-censor
     571
     572<procedure>(<writer>-censor f m)</procedure>
     573
     574Creates a monad resulting from the application of the provided function on the given monad, censoring the values that were in the given monad.
     575
     576======= Example
     577
     578<enscript highlight="scheme">
     579#;> (do <writer>
     580        (/m! censor (lambda (l) (map (lambda (v) (+ v 1)) l))
     581                   (/m! tell '(1 2 3))))
     582(() 2 3 4)
    245583</enscript>
    246584
     
    260598=== Version History
    261599
     600; 3.0 : Renamed :! to /m! and : to /m due to : already being used for explicit specialization (oops)                                                                                                                                                                     
     601; 2.4 : Added :! keyword, fixed : keyword                                                                                                                                                                                                                               
     602; 2.3 : Added fail function for all monads which defaults to assert, but is definied appropriately for the &lt;exception&gt; and &lt;maybe&gt; monads. Added : keyword to using and do-using. Added &gt;&gt;=, return and fail bindings to do-using syntax. 
    262603; 2.2 : Added failure states for monads
    263604; 2.1 : Rewrote API to allow for terser execution and a simpler interface. Removed use of promises completely. Removed doto-using, run-chain, and run from the API completely. Added do-using syntax. Maybe monad is now self-defined for it's value or no-value states.
Note: See TracChangeset for help on using the changeset viewer.