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

笛卡尔积在斯卡拉兹中

发布时间:2020-12-16 18:39:12 所属栏目:安全 来源:网络整理
导读:在 Eric Torreborre’s blogpost号纸上的 Eric Torreborre’s blogpost中,他描述了横越的笛卡尔积也是如何遍历. 任何人都可以使用scalaz library向我展示这个例子,因为我无法弄明白.让我们说问题是,对于List [Int],我想提供以下两个: 列表中元素的Int总和 L
在 Eric Torreborre’s blogpost号纸上的 Eric Torreborre’s blogpost中,他描述了横越的笛卡尔积也是如何遍历.

任何人都可以使用scalaz library向我展示这个例子,因为我无法弄明白.让我们说问题是,对于List [Int],我想提供以下两个:

>列表中元素的Int总和
> List [String],其元素是通过将“Z”附加到Ints的String表示形式而创建的

我的理解是,我可以使用遍历执行此操作,但这样做的方式只是实际遍历我的结构一次,不像这个解决方案:

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个独立定义的函数,可以组成只进行一次遍历.

(编辑:李大同)

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

    推荐文章
      热点阅读