gpt4 book ai didi

clojure - 是否可以在 Clojure 中执行 Free Monad?

转载 作者:行者123 更新时间:2023-12-04 10:39:13 32 4
gpt4 key购买 nike

Konrad Hinsen Clojure 中的 Monads 有一些出色的工作, Jim DueyLeonardo Borges .

我的问题是 - 是否可以在 Clojure 中执行 Free Monad?

This is an example in Haskell来自一篇关于 Scala 的文章:

data Free f r = Free (f (Free f r)) | Pure r

这是相应的 Scala 示例
sealed abstract class Free[S[+_], +A](implicit S: Functor[S]) {
final def map[B](f: A => B): Free[S, B] =
flatMap(a => Return(f(a)))

final def flatMap[B](f: A => Free[S, B]): Free[S, B] = this match {
case Gosub(a, g) => Gosub(a, (x: Any) => Gosub(g(x), f))
case a => Gosub(a, f)
}
...
}

最佳答案

是的,按照 Luis Casillas 的回答,这里是 Free clojure 中的一个实现Clojure 中的 monad。

    (use 'clojure.algo.monads)

;; data Free f r = Free (f (Free f r)) | Pure r
(defn pure [v] {:t :pure :v v})
(defn impure [v] {:t :impure :v v })

(defn free-monad
[fmap]
(letfn [
(fm-result [v] (pure v))
(fm-bind [mv mf]
(if (= :pure (:t mv))
(mf (:v mv)) ;; Pure a >>= f = f a
(impure ;; Free fa >>= f = Free (fmap (>>=f) fa)
((fmap (fn [lmv] (fm-bind lmv mf))) (:v mv)))))
]
{
:m-result fm-result
:m-bind fm-bind
:m-zero ::undefined
:m-plus ::undefined
}
)
)

以及来自 Why free monads matter 的示例:

玩具语言的定义。
    ;; Toy language
;;
(defn output [c n] [{:t :output :v c}, n])
(defn bell [n] [{:t :bell}, n])
(defn done [] [{:t :done}, nil])
(defn toy-fmap [f]
(fn [[e c]]
(if (= :done (:t e))
[e c]
[e (f c)]
))
)

玩具语言的 monad 定义 + 辅助函数
    ;;
(def tt-monad
(free-monad toy-fmap))


(defn liftF [toy]
(impure ((toy-fmap (fn [c] (pure c))) toy))
)

(defn m-output [x] (liftF (output x nil)))
(defn m-bell [] (liftF (bell nil)))
(defn m-done [] (liftF (done)))
(defn f-m-done [_] (m-done))

并检查一些规则:
    ;; return "a" >>= output  is Free(Output "a", ())
;; {:t :impure, :v [{:t :output, :v \a} {:t :pure, :v nil}]}
(with-monad tt-monad
(m-bind (m-result \a) m-output)
)


;; output "a" >>= return is Free(Output "a", ())
;; {:t :impure, :v [{:t :output, :v \a} {:t :pure, :v nil}]}
(with-monad tt-monad
(m-bind (m-output \a) m-result)
)

;; ((output 'A' >> done) >> output 'C')
(with-monad tt-monad
(m-bind (m-bind (m-output \a) f-m-done) (fn [_] (m-output \c))))

;;(output 'A' >> (done >> output 'C')) is output 'A' Done
(with-monad tt-monad
(m-bind (m-output \a) (fn [x] (m-bind (m-done) (fn [_] (m-output \c))))))

这在数据结构的可读性方面可以得到很大改善。
评论和改进最受欢迎。

关于clojure - 是否可以在 Clojure 中执行 Free Monad?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20171057/

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