加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

什么是Clojure相当于Scalaz Foldable的折叠图?

发布时间:2020-12-16 18:57:40 所属栏目:安全 来源:网络整理
导读:在 Scalaz trait Foldable 中,我们看到 method foldMap ,其描述如下 Map each element of the structure to a [[scalaz.Monoid]],and combine the results. def foldMap[A,B](fa: F[A])(f: A = B)(implicit F: Monoid[B]): B 你可以像这样使用它: scala Lis
在 Scalaz trait Foldable中,我们看到 method foldMap,其描述如下

Map each element of the structure to a [[scalaz.Monoid]],and combine the results.

def foldMap[A,B](fa: F[A])(f: A => B)(implicit F: Monoid[B]): B

你可以像这样使用它:

scala> List(1,2,3) foldMap {identity}
res1: Int = 6

scala> List(true,false,true,true) foldMap {Tags.Disjunction}
res2: scalaz.@@[Boolean,scalaz.Tags.Disjunction] = true

我的问题是:Clojure相当于Scalaz Foldable的折图?

解决方法

默认情况下,Clojure没有monadic组合.为此你需要像 algo.monads或 fluokitten这样的库.

Haskell和Skalaz中的monoid是一个实现三个函数的类:

> mempty返回标识元素
> mappend结合了两个相同类型的值
> mconcat用于将该类型的集合转换为items和v.v.

Clojure没有折叠函数可以调用所有这三个函数; reduce是用于累积集合的高阶函数.

默认情况下,它需要3个参数:reducer函数,累加器和集合. reducer函数用于一次合并累加器和集合中的一个项目.它不需要接受像mappend这样的相同类型.第三个是集合,这就是不需要mconcat的原因.

在Clojure的1.5 clojure.reducers和clojure.core / reduce的上下文中,有一个monoid:一个函数在没有参数的情况下调用时返回它的identity元素.

例如:

(+) => 0 
(*) => 1
(str) => ""
(vector) => []
(list) => ()

这个’monoid’函数在reduce的两个参数版本中用作reducer;它的’monoidal identity’或mempty被称为创建初始累加器.

(减少[1 2 3])=> (reduce()[1 2 3])=> (减少0 [1 2 3])

因此,如果你想在这里翻译这些例子,你需要找到或创建一个具有这种’monoid’实现的函数,以便在双arity reduce中使用它.

对于脱节,Clojure有或:

(defmacro or
  "Evaluates exprs one at a time,from left to right. If a form
  returns a logical true value,or returns that value and doesn't
  evaluate any of the other expressions,otherwise it returns the
  value of the last expression. (or) returns nil."
  {:added "1.0"}
  ([] nil)
  ([x] x)
  ([x & next]
      `(let [or# ~x]
         (if or# or# (or ~@next)))))

它确实有’monoid’实现,([] nil).但是,或者实现为支持短路的宏,并且只能在要扩展的表达式中使用,而不能作为函数参数使用:

(reduce or [false true false true true])
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/or,compiling

所以我们需要一个’新’或者这是一个真正的分离函数.它还应该实现一个返回nil的无冗余版本:

(defn newor
  ([] nil)
  ([f s] (if f f s)))

所以现在我们有一个带有’monoid’实现的函数,你可以在双arity reduce中使用它:

(reduce newor [true false true true])
=> true

看起来有点复杂,直到你理解为什么Clojure实现或作为多个arity宏

(or true false true true)
=> true

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读