From b4ac0fa66a3212fad3373a68d84d4b74c5fd309c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= Date: Mon, 18 Mar 2019 21:57:47 +0100 Subject: Wrote a bunch of documentation. --- monad/optional.scm | 10 +++++++++- monad/stack.scm | 13 +++++++------ monad/state.scm | 33 +++++++++++++++++++-------------- 3 files changed, 35 insertions(+), 21 deletions(-) (limited to 'monad') diff --git a/monad/optional.scm b/monad/optional.scm index 015fc90..06c0e67 100644 --- a/monad/optional.scm +++ b/monad/optional.scm @@ -1,3 +1,10 @@ +;;; Commentary: +;; +;; Your classical optional (Maybe) monad. +;; It has the constructors @code{just} and @code{nothing}. +;; +;;; Code: + (define-module (monad optional) #:use-module (oop goops) #:use-module (ice-9 match) @@ -34,7 +41,8 @@ the value embedded in maybe-val" default)) (define ((wrap-maybe proc) . values) - "Wraps a function in an optional monad, where #f returns are translated to nothing." + "Wraps a function in an optional monad, where #f returns are translated to +nothing." (let ((v (apply proc values))) (if v (just v) (nothing)))) diff --git a/monad/stack.scm b/monad/stack.scm index 8d25303..fee48a6 100644 --- a/monad/stack.scm +++ b/monad/stack.scm @@ -1,14 +1,15 @@ +;;; Commentary: +;; Simple stateful stack module for showing the state monad +;; in action. These functions assume that they are in a +;; (state list) monad. But dynamic types! +;; +;; TODO test these for empty stack +;;; Code: (define-module (monad stack) #:export (pop peek push) #:use-module (monad) #:use-module (monad state)) -;;; Simple stateful stack module for showing the state monad -;;; in action. These functions assume that they are in a -;;; (state list) monad. But dynamic types! - -;;; TODO test these for empty stack - (define (pop) (do st <- (get) let top = (car st) diff --git a/monad/state.scm b/monad/state.scm index 471e756..40c9ff5 100644 --- a/monad/state.scm +++ b/monad/state.scm @@ -1,13 +1,26 @@ +;;; Commentary: +;; +;; The state monad! +;; State is best modelled monadically as a function taking a state object, and +;; returning another state object. This state object is in turn represented as i +;; list where the first value is the last value returned, and the secound value +;; is the internal state. +;; +;; All access to this internal value is done through the methods @code{get}, +;; @code{put}, and @code{modify}. +;; +;; One side effect of the @code{} object not being directly accessible is +;; that my trick for multiple dispatch return doesn't work. Which is why this +;; modules also exports @code{return-state} directly. +;; +;;; Code: + (define-module (monad state) #:use-module (oop goops) #:use-module (ice-9 match) #:use-module (monad) #:export (return-state run-state get put modify) - #:re-export (>>= >> fmap return)) - - -;; Alternative implementation of get. -;; See https://hackage.haskell.org/package/mtl-2.2.1/docs/src/Control.Monad.State.Class.html#get + #:re-export (>>= >> return)) ;;; newtype State = st-list -> st-list @@ -48,10 +61,6 @@ ((v _) ((proc (f v)) new-st-list))))) -;; (define-stateful-method ((>> (a ) (b )) st-list-a) -;; (let ((st-list-b ((proc a) st-list-a))) -;; ((proc b) st-list-b))) - (define-stateful ((return-state v) st-list) "Sets the return value to v" (cons v (cdr st-list))) @@ -69,15 +78,11 @@ (list '() v)) (define-stateful ((modify proc) st-list) + "Applies proc to the value stored in state, and stores it back" (match st-list ((r s) (list '() (proc s))))) -;; (define-stateful-method ((fmap (f ) (s )) st-list) -;; (match ((proc s) st-list) -;; ((r st) -;; (list (f r) st)))) - (define-method (run-state (st ) init) "Exec state with init as starting state value and st." ((proc st) (list init init))) -- cgit v1.2.3