Skip to content

Instantly share code, notes, and snippets.

@nyuichi
Created September 30, 2015 06:29
Show Gist options
  • Save nyuichi/560c6c3fe8f97eee9bf3 to your computer and use it in GitHub Desktop.
Save nyuichi/560c6c3fe8f97eee9bf3 to your computer and use it in GitHub Desktop.
;;; data Comonad f a where
;;; Comonad a ((Comonad f a -> b) -> f b)
; counit : Comonad f a -> a
; cobind : Comonad f a -> (Comonad f a -> b) -> Comonad f b
; lift : (f a -> a) -> (f a -> (f a -> b) -> f b) -> (f a -> Comonad f a)
; run : Comonad f a -> f a
(define Comonad cons)
(define (counit m) (car m))
(define (cobind m f)
(let ((v (car m)) (k (cdr m)))
(Comonad (f m) (lambda (p) (k (lambda (n) (p (cobind n f))))))))
(define (lift u n)
(define (unrun m)
(Comonad (u m)
(lambda (f)
(n m (lambda (x) (f (unrun x)))))))
unrun)
(define (run m)
(let ((v (car m)) (k (cdr m)))
(k (lambda (_) v))))
; data Monad f a where ; Monad as a data structure
; Unit : a -> Monad f a
; Bind : f a -> (a -> Monad f b) -> Monad f b
; unit : a -> Monad f a
; bind : Monad f a -> (a -> Monad f b) -> Monad f b
; lift : f a -> Monad f a
; run : (a -> f a) -> (f b -> (b -> f a) -> f a) -> (Monad f a -> f a)
;;; Monad Constructors
(define (Unit x) (cons x #f))
(define (Bind m k) (cons m k))
;;; Monad Operators
(define (unit x) (Unit x))
(define (bind m f)
(let ((v (car m)) (k (cdr m)))
(if k
(Bind v (lambda (x) (bind (k x) f)))
(k v))))
;;; Interoperation
(define (lift x) (Bind x Unit))
(define (run u n)
(define (unlift m)
(let ((v (car m)) (k (cdr m)))
(if k
(n v (lambda (x) (unlift (k x))))
(u v))))
unlift)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment