Last active
January 12, 2018 02:35
-
-
Save elrikdante/78c8cea6354b185c530ba6ecce2c05f4 to your computer and use it in GitHub Desktop.
practising clojure
This file contains hidden or 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
;;lumo -i prelude.cljc -e "(require 'prelude) (prelude/mmap (comp list identity) (list 1 2 4)) (prelude/foldl + 0 [1 2 3 4]) (prelude/foldr + 0 [1 2 3 4]) (prelude/list->Sum (range 50)) (prelude/++ (prelude/Sum 5) (prelude/Sum 6)) (prelude/->Sum (range 5)) (prelude/++M (prelude/->Max 10) (prelude/->Max 20)) (reduce prelude/++M (map prelude/->Max (range 50)))" | |
;https://gist.github.com/anonymous/0d34f91b5947e732a78b0e595de5a89c | |
;https://gist.github.com/anonymous/3b7cc262a57f0d6451d65751b4f3334d#file-prelude-cljc | |
(ns prelude) | |
;(defmacro comment ([form &args] ())) | |
;drop form | |
;(defmacro comment ([form &args] ())) | |
;(defmacro comment ([&args] ())) | |
(defn take | |
"Returns a lazy sequence of the first n items in coll, or all items if | |
there are fewer than n. Returns a stateful transducer when | |
no collection is provided." | |
([n] | |
{:pre [(number? n)]} | |
(fn [rf] | |
(let [na (volatile! n)] | |
(fn | |
([] (rf)) | |
([result] (rf result)) | |
([result input] | |
(let [n @na | |
nn (vswap! na dec) | |
result (if (pos? n) | |
(rf result input) | |
result)] | |
(if (not (pos? nn)) | |
(ensure-reduced result) | |
result))))))) | |
([n coll] | |
{:pre [(number? n)]} | |
(lazy-seq | |
(when (pos? n) | |
(when-let [s (seq coll)] | |
(cons (first s) (take (dec n) (rest s)))))))) | |
(defn mmap [function sequence] | |
(apply concat (map function sequence))) | |
(defn foldl [b->a->b b as] | |
(if (empty? as) | |
b | |
(foldl b->a->b (b->a->b b (first as)) (rest as)))) | |
(defn foldr [a->b->b b as] | |
(if (empty? as) | |
b | |
(a->b->b (foldr a->b->b b (rest as) ) (first as)))) | |
(defrecord _Sum [getSum]) | |
(defn Sum [x] (_Sum. (identity x))) | |
(defn ++Sum | |
([sumA] sumA) | |
([sumA sumB] (let [s' (:getSum sumA) | |
e' (:getSum sumB)] | |
(Sum (+ s' e'))))) | |
(defn list->Sum [col] (foldl ++Sum (Sum 0) (map Sum col))) | |
(def ->Sum list->Sum) | |
(defrecord _Max [getMax]) | |
(def Max (comp #(_Max. %) identity)) | |
(def ->Max Max) | |
(defn <$>Max | |
([maxA] maxA) | |
([maxA A->B] (let [a (:getMax maxA)] | |
(Max (A->B a))))) | |
(defn ++Max | |
([maxA] maxA) | |
([maxA maxB] (let [m (:getMax maxA) | |
n (:getMax maxB)] | |
(Max (max m n))))) | |
(defn list->Max [col] (foldl ++Max (Max (first col)) (map Max (rest col)))) | |
(defrecord _Min [getMin]) | |
(def Min (comp #(_Min. %) identity)) | |
(defn ++Min | |
([minA] minA) | |
([minA minB] (let [minL (:getMin minA) | |
minR (:getMin minB)] | |
(Min (min minL minR) )))) | |
(defn list->Min [col] (foldl ++Min (Min (first col)) (map Min (rest col)))) | |
(defrecord _First [getFirst]) | |
(def First (comp #(_First. %) identity)) | |
(defn ++First | |
([firstA] firstA) | |
([firstA firstB] (let [f (:getFirst firstA)] | |
(if f (First f) (First (:getFirst firstB)))))) | |
(defrecord _Last [getLast]) | |
(def Last (comp #(_Last. %) identity)) | |
(defn ++Last | |
([lastA] lastA) | |
([lastA lastB] (let [g (:getLast lastB)] | |
(if g (Last g) (Last (:getLast lastA)))))) | |
(defrecord _Fold [foldStep foldSum]) | |
(defn Fold [fStep fSum] (_Fold. fStep fSum)) | |
(def IdentityFold (Fold list concat)) | |
(def SumFold (Fold Sum :getSum)) | |
(def MinFold (Fold Min :getMin)) | |
(def MaxFold (Fold Max :getMax)) | |
(def FirstFold (Fold First :getFirst)) | |
(def LastFold (Fold Last :getLast)) | |
(def LengthFold (Fold (fn [_] (Sum 1)) :getSum)) | |
(defrecord _Avg [avgNumerator avgDenominator]) | |
(defn Avg | |
([x] (_Avg. x 1)) | |
([x y] (_Avg. x y))) | |
(def AvgFold (Fold Avg (fn [{:keys [avgNumerator avgDenominator]}] (/ avgNumerator avgDenominator)))) | |
(defn ++Avg | |
([avg] | |
avg) | |
([avg1 avg2] | |
(Avg | |
(+ (:avgNumerator avg1) (:avgNumerator avg2)) | |
(+ (:avgDenominator avg1) (:avgDenominator avg2))))) | |
(defn _runFold [ {:keys [ foldStep foldSum ],:as fold} | |
;(comment " ") | |
input | |
;(comment " ") | |
m-empty | |
;(comment " ") | |
m-append | |
;(comment "") | |
] | |
(let [inputs (map foldStep input)] | |
(foldSum (foldl m-append m-empty inputs)))) | |
(defn compFold | |
([foldA] foldA) | |
([ | |
{:keys [ foldStep foldSum ] , :as foldA } | |
stepA foldStep | |
sumA foldSum | |
{:keys [ foldStep foldSum ] , :as foldB } | |
stepB foldStep | |
sumB foldSum | |
] | |
(let [stepAx (:foldStep foldA) | |
sumAx (:foldSum foldA) | |
stepBx (:foldStep foldB) | |
sumBx (:foldSum foldB)] | |
; :f :o ;O | |
(Fold (comp stepA stepB) (comp sumA sumB))))) | |
(defn runFold-Sum [fold input] (_runFold fold (rest input) (Sum (first input)) ++Sum)) | |
(defn runFold-Min [fold input] (_runFold fold (rest input) (Min (first input)) ++Min)) | |
(defn runFold-Max [fold input] (_runFold fold (rest input) (Max (first input)) ++Max)) | |
(defn runFold-First [fold input] (_runFold fold input (First nil) ++First)) | |
(defn runFold-Last [fold input] (_runFold fold input (Last nil) ++Last)) | |
(defn runFold-Avg [fold input] (_runFold fold input (Avg 0.0 0.0) ++Avg)) | |
(defn runFold-Identity [fold input] (_runFold fold input (list) concat)) | |
(defn generic-length [is] (runFold-Sum LengthFold is)) | |
(defn generic-head [is] (runFold-First FirstFold is)) | |
(defn generic-last [is] (runFold-Last LastFold is)) | |
;(comment | |
;lumo -i prelude.cljc -e " | |
; (require 'prelude) | |
; (prelude/mmap (comp list identity) (list 1 2 4)) | |
; (prelude/foldl + 0 [1 2 3 4]) | |
; (prelude/foldr + 0 [1 2 3 4]) | |
; (prelude/list->Sum (range 50)) | |
; (prelude/++Sum (prelude/Sum 5) (prelude/Sum 6)) | |
; (prelude/->Sum (range 5)) | |
; (prelude/++Max (prelude/->Max 10) (prelude/->Max 20)) | |
; (prelude/<$>Max (reduce prelude/++Max (map prelude/->Max (range 50))) (comp inc (fn [x] (js/console.log x) x))) | |
; (prelude/list->Min (range 45 50)) | |
; {:x (prelude/runFold-Max (prelude/compFold prelude/IdentityFold prelude/MaxFold) (identity (range 1 40)))} | |
; (prelude/generic-length (seq [1 1 1 1 1])) | |
; (prelude/generic-head [2 1 4]) | |
; (prelude/generic-last [2 1 4]) | |
; " | |
;) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment