-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial implementation including Reader and State effects.
- Loading branch information
Pauli Jaakkola
committed
Aug 27, 2018
1 parent
58d4c5d
commit e9a7eda
Showing
5 changed files
with
107 additions
and
11 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,5 @@ pom.xml.asc | |
/.nrepl-port | ||
.hgignore | ||
.hg/ | ||
.idea/ | ||
*.iml |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
(defproject fell "0.1.0-SNAPSHOT" | ||
:description "FIXME: write description" | ||
:description "Freer monads for Clojure" | ||
:url "http://example.com/FIXME" | ||
:license {:name "Eclipse Public License" | ||
:url "http://www.eclipse.org/legal/epl-v10.html"} | ||
:dependencies [[org.clojure/clojure "1.8.0"]]) | ||
:dependencies [[org.clojure/clojure "1.9.0"] | ||
[funcool/cats "2.2.0"]]) |
This file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
(ns fell.core | ||
(:require [cats.protocols :refer [Contextual Extract -extract Context Monad]])) | ||
|
||
(defn- singleton-queue [v] | ||
#?(:clj (conj clojure.lang.PersistentQueue/EMPTY v) | ||
:cljs #queue [v])) | ||
|
||
(declare context) | ||
|
||
(deftype Pure [v] | ||
Contextual | ||
(-get-context [_] context) | ||
|
||
Extract | ||
(-extract [_] v)) | ||
|
||
(deftype Impure [request cont] | ||
Contextual | ||
(-get-context [_] context)) | ||
|
||
(def context | ||
(reify | ||
Context | ||
|
||
Monad | ||
(-mreturn [_ v] (Pure. v)) | ||
(-mbind [_ mv f] | ||
(condp instance? mv | ||
Pure (f (-extract mv)) | ||
Impure (Impure. (.-request mv) (conj (.-cont mv) f)))))) | ||
|
||
(defn- apply-queue [queue v] | ||
(let [mv ((peek queue) v) | ||
queue* (pop queue)] | ||
(if (seq queue*) | ||
(condp instance? mv | ||
Pure (recur queue* (-extract mv)) | ||
Impure (Impure. (.-request mv) (into (.-cont mv) queue*))) | ||
mv))) | ||
|
||
(defn append-handler [queue handle] | ||
(comp handle (partial apply-queue queue))) | ||
|
||
(defn send [request] | ||
(Impure. request (singleton-queue ->Pure))) | ||
|
||
(defn handle-relay [can-handle? ret handle mv] | ||
(condp instance? mv | ||
Pure (ret (-extract mv)) | ||
Impure (let [request (.-request mv) | ||
cont (append-handler (.-cont mv) | ||
(partial handle-relay can-handle? ret handle))] | ||
(if (can-handle? (.-request mv)) | ||
(handle request cont) | ||
(Impure. request (singleton-queue cont)))))) | ||
|
||
(defn run-reader [mv ctx] | ||
(handle-relay #(= (first %) :reader/get) ->Pure (fn [[_] cont] (cont ctx)) mv)) | ||
|
||
(defn state-runner [label] | ||
(fn run-state [mv domain-state] | ||
(condp instance? mv | ||
Pure (Pure. [(-extract mv) domain-state]) | ||
Impure (let [[tag subtag state* :as request] (.-request mv) | ||
make-cont (fn [domain-state] | ||
(append-handler (.-cont mv) #(run-state % domain-state)))] | ||
(if (= tag label) | ||
(case subtag | ||
:get ((make-cont domain-state) domain-state) | ||
:set ((make-cont state*) nil)) | ||
(Impure. request (singleton-queue (make-cont domain-state)))))))) | ||
|
||
(def run -extract) |