gpt4 book ai didi

clojure - Clojure 中的 reader monad 和偏函数有什么区别?

转载 作者:行者123 更新时间:2023-12-02 17:09:28 25 4
gpt4 key购买 nike

Leonardo Borges has放在一起a fantastic presentation关于 Clojure 中的 Monad。他在其中描述了 Clojure 中的 reader monad using the following code :

;; 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 中的 reader monad 和部分函数有什么区别?

最佳答案

阅读器单子(monad)是一组我们可以用来干净地编写阅读器的规则。您可以使用 partial 来创建阅读器,但它并没有真正为我们提供将它们组合在一起的方法。

例如,假设您想要一个能够将其读取的值翻倍的阅读器。您可以使用 partial 来定义它:

(def doubler
(partial * 2))

您可能还需要一个读取器,将其读取的任何值加一:

(def plus-oner
(partial + 1))

现在,假设您想将这些人合并到一个读取器中,以添加他们的结果。你可能最终会得到这样的结果:

(defn super-reader
[env]
(let [x (doubler env)
y (plus-oner env)]
(+ x y)))

请注意,您必须将环境显式转发给这些读者。真是太糟糕了,对吧?使用 reader monad 提供的规则,我们可以获得更清晰的组合:

(def super-reader
(do-m reader-m
[x doubler
y plus-oner]
(+ x y)))

关于clojure - Clojure 中的 reader monad 和偏函数有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22264115/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com