Last active
January 1, 2018 14:57
-
-
Save lagenorhynque/84241a95eff3411d1e25d9610537552e to your computer and use it in GitHub Desktop.
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
| (ns cli | |
| (:require [clojure.spec.alpha :as s])) | |
| (s/fdef sum | |
| :args (s/cat :coll (s/coll-of number?)) | |
| :ret number?) | |
| (defn sum [coll] | |
| (if (empty? coll) | |
| 0 | |
| (+ (first coll) (sum (rest coll))))) | |
| (s/fdef length | |
| :args (s/cat :coll coll?) | |
| :ret nat-int?) | |
| (defn length [coll] | |
| (if (empty? coll) | |
| 0 | |
| (inc (length (rest coll))))) | |
| ;; foldを利用した版 | |
| (s/fdef fold | |
| :args (s/cat :f ifn? | |
| :val any? | |
| :coll coll?) | |
| :ret any?) | |
| (defn fold [f val coll] | |
| (if (empty? coll) | |
| val | |
| (recur f (f val (first coll)) (rest coll)))) | |
| (defn sum' [coll] | |
| (fold + 0 coll)) | |
| (defn length' [coll] | |
| (fold (fn [len _] (inc len)) 0 coll)) | |
| (s/fdef get-at | |
| :args (s/and (s/cat :idx nat-int? | |
| :coll (s/coll-of any? :min-count 1)) | |
| (fn [{:keys [idx coll]}] | |
| (< idx (count coll)))) | |
| :ret any?) | |
| (defn get-at [idx coll] | |
| (if (zero? idx) | |
| (first coll) | |
| (recur (dec idx) (rest coll)))) | |
| (s/fdef group-count | |
| :args (s/cat :coll coll?) | |
| :ret (s/map-of any? nat-int?)) | |
| (defn group-count [coll] | |
| (letfn [(group-count-impl [coll m] | |
| (if (empty? coll) | |
| m | |
| (recur (rest coll) | |
| (update m (first coll) (fnil inc 0)))))] | |
| (group-count-impl coll {}))) | |
| (defn group-count' | |
| ([coll] | |
| (group-count' coll {})) | |
| ([coll m] | |
| (if (empty? coll) | |
| m | |
| (recur (rest coll) | |
| (update m (first coll) (fnil inc 0)))))) | |
| (s/fdef max-count | |
| :args (s/cat :coll (s/coll-of (s/tuple any? nat-int?))) | |
| :ret (s/nilable nat-int?)) | |
| (defn max-count [coll] | |
| (letfn [(max-count-impl [coll max-elem max-cnt] | |
| (if (empty? coll) | |
| max-elem | |
| (let [[[head-elem head-cnt] & tail] coll] | |
| (if (> head-cnt max-cnt) | |
| (recur tail head-elem head-cnt) | |
| (recur tail max-elem max-cnt)))))] | |
| (max-count-impl (sort coll) nil 0))) | |
| (defn max-count' [coll] | |
| (letfn [(max-count-impl [coll max-elem max-cnt] | |
| (if (empty? coll) | |
| max-elem | |
| (let [[[head-elem head-cnt] & tail] coll] | |
| (if (>= head-cnt max-cnt) | |
| (recur tail head-elem head-cnt) | |
| (recur tail max-elem max-cnt)))))] | |
| (max-count-impl (sort coll) nil 0))) | |
| (s/fdef mean | |
| :args (s/cat :numbers (s/coll-of number? :min-count 1)) | |
| :ret number?) | |
| (defn mean [numbers] | |
| (/ (sum numbers) (length numbers))) | |
| (s/fdef median | |
| :args (s/cat :numbers (s/coll-of number? :min-count 1)) | |
| :ret number?) | |
| (defn median [numbers] | |
| (get-at (quot (length numbers) 2) (sort numbers))) | |
| (s/fdef mode | |
| :args (s/cat :numbers (s/coll-of number?)) | |
| :ret (s/nilable number?)) | |
| (defn mode [numbers] | |
| (-> numbers group-count max-count)) | |
| (defn -main [& args] | |
| (let [numbers (map #(Integer/parseInt %) args)] | |
| (println "mean:" (mean numbers)) | |
| (println "median:" (median numbers)) | |
| (println "mode:" (mode numbers)))) |
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
| {:deps {org.clojure/clojure {:mvn/version "1.9.0-RC1"} | |
| org.clojure/test.check {:mvn/version "0.9.0"} | |
| funcool/cats {:mvn/version "2.1.0"}} | |
| :paths ["."]} |
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
| (ns handson-tp | |
| (:require [cats.context :as ctx] | |
| [cats.core :as m] | |
| [cats.protocols :as p] | |
| [cats.util :as util] | |
| [clojure.spec.alpha :as s])) | |
| (s/fdef length | |
| :args (s/cat :coll coll?) | |
| :ret nat-int?) | |
| (defn length [coll] | |
| (if (empty? coll) | |
| 0 | |
| (inc (length (rest coll))))) | |
| (s/fdef sum | |
| :args (s/cat :coll coll? | |
| :ctx (s/? #(satisfies? p/Monoid %))) | |
| :ret any?) | |
| (def sum-monoid | |
| (reify | |
| p/Context | |
| p/Semigroup | |
| (-mappend [_ a b] | |
| (+ a b)) | |
| p/Monoid | |
| (-mempty [_] | |
| 0) | |
| p/Printable | |
| (-repr [_] | |
| "#<SumMonoid>"))) | |
| (util/make-printable (type sum-monoid)) | |
| (def prod-monoid | |
| (reify | |
| p/Context | |
| p/Semigroup | |
| (-mappend [_ a b] | |
| (* a b)) | |
| p/Monoid | |
| (-mempty [_] | |
| 1) | |
| p/Printable | |
| (-repr [_] | |
| "#<ProdMonoid>"))) | |
| (util/make-printable (type prod-monoid)) | |
| (def string-monoid | |
| (reify | |
| p/Context | |
| p/Semigroup | |
| (-mappend [_ a b] | |
| (str a b)) | |
| p/Monoid | |
| (-mempty [_] | |
| "") | |
| p/Printable | |
| (-repr [_] | |
| "#<StringMonoid>"))) | |
| (util/make-printable (type string-monoid)) | |
| (defn sum | |
| ([coll] | |
| (reduce m/mappend (m/mempty) coll)) | |
| ([coll ctx] | |
| (ctx/with-context ctx | |
| (reduce m/mappend (m/mempty) coll)))) | |
| (defn -main [& args] | |
| (doseq [monoid [sum-monoid prod-monoid string-monoid]] | |
| (ctx/with-context monoid | |
| (println "with" monoid) | |
| (println " sum []:" (sum [])) | |
| (println " sum [1 2 3 4 5]:" (sum [1 2 3 4 5]))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment