笛卡尔积在斯卡拉兹中
在
Eric Torreborre’s blogpost号纸上的
Eric Torreborre’s blogpost中,他描述了横越的笛卡尔积也是如何遍历.
任何人都可以使用scalaz library向我展示这个例子,因为我无法弄明白.让我们说问题是,对于List [Int],我想提供以下两个: >列表中元素的Int总和 我的理解是,我可以使用遍历执行此操作,但这样做的方式只是实际遍历我的结构一次,不像这个解决方案: val xs = List(1,2,3,4) val (sum,strings) = (xs.sum,xs map (_.toString + "Z")) 注1 – 我知道还有其他方法可以做到这一点,我不需要遍历这个例子,也不一定是最简单的解决方法.但是,我试图理解遍历,所以我真的在寻找所述问题的答案 编辑 – 感谢missfaktor下面显示如何使用State执行此操作.我想我想知道的是我如何编写两个独立的计算.例如;我的职能在概念上如下: val shape = (_ : List[Int]) map (_.toString + "Z") val accum = (_ : List[Int]).sum 我希望这些累积机制彼此独立,然后选择是否使用其中一个或两个遍历我的List [Int].我想象一些代码有点像这样: xs traverse shape //A List[String] xs traverse accum //An Int xs traverse (shape <x> accum) //The pair (List[String],Int) Eric意味着这是可能的,但我不知道如何做到这一点?即我没有看到如何定义形状和累积的方式,因为它们可以组成,也不知道如何组成它们. 注2:形状和累积并不意味着字面上具有上述签名的功能.它们是具有执行上述遍历所必需的类型的表达式. 解决方法
我在Jason的基础上添加了我自己的答案,以显示遍历列表的不同方式:
import org.specs2._ import scalaz.std.anyVal._,scalaz.std.list._ import scalaz._,std.tuple._ import scalaz.{Monoid,Applicative} class TraverseSpec extends mutable.Specification { implicit val Sum = Monoid[Int].applicative implicit val Concat = Monoid[List[String]].applicative implicit val A: Applicative[({type λ[α] = (Int,List[String])})#λ] = Sum.product[({type λ[α]=List[String]})#λ](Concat) val xs = List(1,4) "traverse - by folding the list with a Monoid" >> { val (sum,text) = Foldable[List].foldMap(xs)(a => (a,List(a.toString + "Z"))) (sum,text) === (10,List("1Z","2Z","3Z","4Z")) } "traverse - with a function returning a tuple" >> { val (sum,text) = A.traverse(xs)(a => (a,text.reverse) === (10,"4Z")) } "traverse - with 2 functions and 2 traversals" >> { val count = (a: Int) => a val collect = (a: Int) => List(a.toString+"Z") val sum = Sum.traverse(xs)(count) val text = Concat.traverse(xs)(collect) (sum,"4Z")) } "traverse - with 2 functions and 1 fused traversal" >> { val sum = (a: Int) => a val collect = (a: Int) => List(a.toString+"Z") implicit def product[A,B,C](f: A => B): Product[A,B] = Product(f) case class Product[A,B](f: A => B) { def <#>[C](g: A => C) = (a: A) => (f(a),g(a)) } val (total,text) = A.traverse(xs)(sum <#> collect) (total,"4Z")) } } 我认为最后一个例子显示了你所追求的东西:2个独立定义的函数,可以组成只进行一次遍历. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |