Granjure
Functor, Applicative, Arrow, and Monad.
Examples
Applicative
(require 'granjure.data.function)
(use '[granjure.control.applicative :only [<*> *> <* <**>]])
(<*> list inc 42) ; (42 43)
(<* list inc 42) ; (42)
(*> list inc 42) ; 43
(<**> inc list 42) ; (42 43)
Arrow
(require 'granjure.data.function)
(use '[granjure.control.arrow :only [fst snd &&& ***]])
(fst inc [42 42]) ; (43 42)
(snd dec [42 42]) ; (42 41)
(&&& inc dec 42) ; (43 41)
(*** inc dec [42 42]) ; (43 41)
Monad
(require 'granjure.data.list)
(use '[granjure.control.monad :only [return >> >>=]])
(def list1 [1 2 3])
(def list2 [4 5 6])
; First, we show ugly deep-nested lambda monad.
(>>= list1 (fn [n]
(>>= list2 (fn [m]
(return (list n m))))))
; ((1 4) (1 5) (1 6) (2 4) (2 5) (2 6) (3 4) (3 5) (3 6))
; But you can use brief and flat syntax. that is the do-notation and the monad-comprehension-notation.
(use '[granjure.control.monad :only [do-m]])
(do-m (
n <- list1 :.
m <- list2 :in
(return (list n m))))
(use '[granjure.control.monad.zip :only [do-mzip]])
(do-mzip ((list n m) | n <- list1 :. m <- list2))
Features
Curried functions
All functions of Granjure are curried.
(use '[granjure.data.tuple :only [tuple2]])
(tuple2 1) ; #<primitive$uncurry$fn__1193 granjure.primitive$uncurry$fn__1193@32b3869c>
((tuple2 1) 2) ; (1 2)
(tuple2 1 2) ; (1 2)
Infix-notation
Each library of Granjure provides infix-notation macros only for syntax-suger. You can use infix-notation if you need, by the infixing library .
(require 'granjure.data.function)
(use '[granjure.control.applicative :only [<*> applicative-rule]])
(use '[infixing.core :only [infixing]])
(defmacro ado [code] (infixing applicative-rule code))
(def f (ado (list <*> inc)))
(f 42) ; (42 43)
Arrows
(require 'granjure.data.function)
(use '[granjure.control.arrow :only [fst snd &&& ***]])
(fst inc [42 42]) ; (43 42)
(snd dec [42 42]) ; (42 41)
(&&& inc dec 42) ; (43 41)
(*** inc dec [42 42]) ; (43 41)
ArrowChoice
(require 'granjure.data.function)
(require 'granjure.data.either)
(import '[granjure.data.either Left Right])
(use '[granjure.control.arrow.choice :only [left right +++ |||]])
(left dec (Left. 42)) ; (Left 41)
(right inc (Left. 42)) ; (Left 42)
(+++ dec inc (Left. 42)) ; (Left 41)
(+++ dec inc (Right. 42)) ; (Right 43)
(||| dec inc (Left. 42)) ; 41
(||| dec inc (Right. 42)) ; 42
More
TODO.