Leonardo Borges は、Clojure のモナドに関する素晴らしいプレゼンテーションをまとめました。その中で彼は、次のコードを使用してClojure のリーダー モナドについて説明しています。
;; Reader Monad
(def reader-m
{:return (fn [a]
(fn [_] a))
:bind (fn [m k]
(fn [r]
((k (m r)) r)))})
(defn ask [] identity)
(defn asks [f]
(fn [env]
(f env)))
(defn connect-to-db []
(do-m reader-m
[db-uri (asks :db-uri)]
(prn (format "Connected to db at %s" db-uri))))
(defn connect-to-api []
(do-m reader-m
[api-key (asks :api-key)
env (ask)]
(prn (format "Connected to api with key %s" api-key))))
(defn run-app []
(do-m reader-m
[_ (connect-to-db)
_ (connect-to-api)]
(prn "Done.")))
((run-app) {:db-uri "user:passwd@host/dbname" :api-key "AF167"})
;; "Connected to db at user:passwd@host/dbname"
;; "Connected to api with key AF167"
;; "Done."
これの利点は、純粋に機能的な方法で環境から値を読み取ることです。
しかし、このアプローチは Clojure の部分関数に非常によく似ています。次のコードを検討してください。
user=> (def hundred-times (partial * 100))
#'user/hundred-times
user=> (hundred-times 5)
500
user=> (hundred-times 4 5 6)
12000
私の質問は次のとおりです。リーダー モナドと Clojure の部分関数の違いは何ですか?