haw*_*eye 6 scala clojure fold scalaz
在Scalaz特征中,Foldable我们看到了具有以下描述的方法foldMap
将结构的每个元素映射到[[scalaz.Monoid]],并合并结果.
def foldMap[A,B](fa: F[A])(f: A => B)(implicit F: Monoid[B]): B
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它:
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
Run Code Online (Sandbox Code Playgroud)
我的问题是:Clojure相当于Scalaz Foldable的折图?
默认情况下,Clojure没有monadic组合.为此你需要像algo.monads或fluokitten这样的库.
Haskell和Skalaz中的monoid是一个实现三个函数的类:
mempty 返回标识元素mappend 结合了两个相同类型的值mconcat 用于将该类型的集合转换为items和vvClojure没有折叠函数可以调用所有这三个函数; reduce是用于累积集合的高阶函数.
默认情况下,它需要3个参数:reducer函数,累加器和集合.reducer函数用于一次合并累加器和集合中的一个项目.它不需要接受相同的类型mappend.第三个总是一个集合,这就是为什么mconcat不需要.
在Clojure的1.5的范围内clojure.reducers,并clojure.core/reduce有是不过一个幺:返回它的标识元素时不带参数调用的函数.
例如:
(+) => 0
(*) => 1
(str) => ""
(vector) => []
(list) => ()
Run Code Online (Sandbox Code Playgroud)
这个'monoid'函数在两个参数版本中用作reducer reduce; 它的'monoidal identity'或被mempty调用来创建初始累加器.
(reduce + [1 2 3]) => (reduce + (+) [1 2 3]) => (reduce + 0 [1 2 3])
因此,如果你想在这里翻译这些例子,你需要找到或创建一个具有这种'monoid'实现的函数,以便在双arity reduce中使用它.
对于脱节,Clojure有or:
(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)))))
Run Code Online (Sandbox Code Playgroud)
它确实有'monoid'实现,([] nil).但是,or实现为支持短路的宏,并且只能在要扩展的表达式中使用,而不能作为函数参数使用:
(reduce or [false true false true true])
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/or, compiling
Run Code Online (Sandbox Code Playgroud)
所以我们需要一个"新" or,这是一个真正的分离功能.它还应该实现一个返回nil的无冗余版本:
(defn newor
([] nil)
([f s] (if f f s)))
Run Code Online (Sandbox Code Playgroud)
所以现在我们有一个带有'monoid'实现的函数,你可以在双arity reduce中使用它:
(reduce newor [true false true true])
=> true
Run Code Online (Sandbox Code Playgroud)
看起来有点复杂,直到你理解为什么Clojure实现or为多个arity宏
(or true false true true)
=> true
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
332 次 |
| 最近记录: |