Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
scalaz中的笛卡尔乘积遍历_Scala_Functional Programming_Traversal_Scalaz - Fatal编程技术网

scalaz中的笛卡尔乘积遍历

scalaz中的笛卡尔乘积遍历,scala,functional-programming,traversal,scalaz,Scala,Functional Programming,Traversal,Scalaz,在这篇文章中,他描述了导线的笛卡尔积也是导线 有人能给我举个例子吗?我想不出来。假设问题是,对于列表[Int]我想提供以下两种: 列表中元素的Int和 一种列表[String],其元素是通过在Ints的字符串表示形式中添加“Z”来创建的 我的理解是,我可以使用遍历来执行此操作,但实际上只能遍历我的结构一次,这与此解决方案不同: val xs = List(1, 2, 3, 4) val (sum, strings) = (xs.sum, xs map (_.toString + "Z"))

在这篇文章中,他描述了导线的笛卡尔积也是导线

有人能给我举个例子吗?我想不出来。假设问题是,对于
列表[Int]
我想提供以下两种:

  • 列表中元素的
    Int
  • 一种
    列表[String]
    ,其元素是通过在
    Int
    s的字符串表示形式中添加“Z”来创建的
  • 我的理解是,我可以使用
    遍历
    来执行此操作,但实际上只能遍历我的结构一次,这与此解决方案不同:

    val xs = List(1, 2, 3, 4)
    val (sum, strings)  = (xs.sum, xs map (_.toString + "Z"))
    
    注意1-我知道还有其他方法可以做到这一点,我不需要遍历这个例子,遍历也不一定是解决这个问题的最清晰的方法。然而,我正试图理解特拉弗斯,所以我真的在寻找上述问题的答案


    编辑-感谢下面的missingfaktor演示了如何使用
    状态
    进行编辑。我想我想知道的是如何组合这两个独立的计算。例如我的职能大致如下:

    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)
    
    xs遍历形状//列表[字符串]
    xs遍历累计//一个整数
    xs遍历(形状累计)//对(列表[String],Int)
    
    Eric暗示这是可能的,但我不知道如何做到这一点,也就是说,我不知道如何定义
    shape
    acum
    ,使它们可以组合,也不知道如何组合它们


    注2表示
    shape
    acum
    并非具有上述签名的函数。它们是具有执行上述遍历所需类型的表达式。

    Debasish Ghosh就这个主题写了一篇不错的文章。根据该帖子中的代码:

    scala> List(1, 2, 3, 4)
    res87: List[Int] = List(1, 2, 3, 4)
    
    scala> .traverse[({ type L[X] = State[Int, X] })#L, String] { cur =>
         |   state { (acc: Int) => (acc + cur, cur.toString + "Z") }
         | }
    res88: scalaz.State[Int,List[String]] = scalaz.States$$anon$1@199245
    
    scala> .apply(0)
    res89: (Int, List[String]) = (10,List(1Z, 2Z, 3Z, 4Z))
    
    编辑:

    您有两个函数
    List[A]=>B
    List[A]=>C
    ,您需要一个函数
    List[A]=>(B,C)
    。这就是
    &&&
    的作用。但这不会使回路熔断。我无法想象,在这种情况下,如何能够熔断回路

    Fwiw,代码:

    scala> val shape = (_ : List[Int]) map (_.toString + "Z")
           val accum = (_ : List[Int]).sum
    shape: List[Int] => List[java.lang.String] = <function1>
    accum: List[Int] => Int = <function1>
    
    scala> val xs = List(1, 2, 3, 4)
    xs: List[Int] = List(1, 2, 3, 4)
    
    scala> (shape &&& accum) apply xs
    res91: (List[java.lang.String], Int) = (List(1Z, 2Z, 3Z, 4Z),10)
    
    最终编辑:(我发誓不再编辑此内容。)


    因为这些概念起源于Haskell,所以我认为将这个问题重新贴在Haskell标签下是一个好主意,我做到了。似乎与我在这篇文章中所说的一致。Hôpe这很有帮助。

    如果我理解正确,您所寻找的内容应该在scala七分支示例:WordCount中描述。它还涉及国家。我在手机上,否则我会提供链接

    以下是链接:

    安德烈亚斯酒店

    编辑:

    好的,再解释一下。我认为你们问题的根本问题是如何组合函数或应用程序。这可以通过应用程序上的产品方法实现

    因此,您需要为两个函数shape和acum定义applicative。其中,accum将被建模为应用程序状态

    如果我们从示例中看这一行: val WordCount=StateT.stateMonad[Int].组合({typeλ[α]=Int})#λ

    它创建了一个“有效”的应用程序(对不起,我的措辞很糟糕)哪个状态。通常在遍历时,只有当前元素。但是,如果要在以前的计算中进行计算,则需要state,因此这将创建一个state applicative,它为它所遍历的每个元素返回1(请参见Monoid[Int].applicative)

    现在要做一些实际的事情,我们需要看看atWordStart方法,您需要定义一个可以使用构造的WordCount应用程序(使用状态)的方法

    这里是Scalaz6的另一个例子,它更简单。我认为观察initialValue和transform1方法的工作方式很重要:

    import scalaz._
    import Scalaz._
    
    object StateTraverseExample {
    
      type StS[x] = State[(Set[Int], Boolean), x] 
    
      def main(args: Array[String]): Unit = {
        println("apparently it works " + countAndMap(Vector.range(0, 20)))
      }
    
      def transform1(i: Int, l: Set[Int], result: Boolean): (Set[Int],Boolean) = {
        if (result || (l contains i))
          (l, true)
        else
          (l + i, false)
       }
    
      def countAndMap(l: Vector[Int]): (Set[Int],Boolean) = {
        val initialValue=(Set.empty[Int], false)
    
        val counts = l.traverse[StS, Unit] { i => 
          state { case (set, result) => (transform1(i,set,result), println(i))   }
        } ~> initialValue
        counts
      }
    }
    

    我现在想起来了,因为这个话题也让我感兴趣。我问eric为什么在他的博客中没有提供应用程序产品。他说他放弃了和打字签名的较量。当时jason修复了scalaz7的WordCount示例(六个示例没有提供动作计数单词)

    您在这里看不到什么大的成功,因为您只是将普通的ol'幺半群推广到应用程序中,所以将它们融合在一起

    import scalaz.std.anyVal._, scalaz.std.list._, scalaz.std.string._
    val Sum = Monoid[Int].applicative
    val Concat = Monoid[List[String]].applicative
    val A: Applicative[({type λ[α] = (Int, List[String])})#λ] = Sum.product[({type λ[α]=List[String]})#λ](Concat)
    
    val xs = List(1, 2, 3, 4)
    val (sum, text) = A.traverse(xs)(a => (a, List(a.toString + "Z")))
    println(sum, text) // 10, List("1Z", "2Z", "3Z", "4Z")
    
    对于所述问题,最好只使用
    Monoid[(Int,List[String])]

    import scalaz._, std.tuple._
    val (sum1, text1) = Foldable[List].foldMap(xs)(a => (a, List(a.toString + "Z")))
    println(sum1, text1) // 10, List("1Z", "2Z", "3Z", "4Z")
    

    如果您想要遍历的效果之一是一个非平凡的应用程序,比如
    State

    我将在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, 2, 3, 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, List(a.toString + "Z")))
        (sum, text.reverse) === (10, List("1Z", "2Z","3Z", "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, text.reverse) === (10, List("1Z", "2Z","3Z", "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, text.reverse) === (10, List("1Z", "2Z","3Z", "4Z"))
      }
    }
    
    import org.specs2_
    导入scalaz.std.anyVal.\u,scalaz.std.list_
    导入scalaz.\uuux,标准元组_
    导入scalaz.{Monoid,Applicative}
    类TraverseSpect扩展了可变规范{
    隐式val Sum=Monoid[Int]。适用
    隐式val Concat=Monoid[List[String]]。适用
    隐式值A:Applicative[({typeλ[α]=(Int,List[String])})#λ]=和积[({typeλ[α]=List[String]})#λ](Concat)
    val xs=List(1,2,3,4)
    “遍历-通过使用幺半群折叠列表”>>{
    val(sum,text)=可折叠的[List].foldMap(xs)(a=>(a,List(a.toString+“Z”))
    (总和,文本)==(10,列表(“1Z”、“2Z”、“3Z”、“4Z”))
    }
    “遍历-使用返回元组的函数”>>{
    val(sum,text)=A.traverse(xs)(A=>(A,List(A.toString+“Z”))
    (和,文本。反转)==(10,列表(“1Z”、“2Z”、“3Z”、“4Z”))
    }
    “遍历-具有2个函数和2个遍历”>>{
    val计数=(a:Int)=>a
    val collect=(a:Int)=>List(a.toString+“Z”)
    val sum=总和遍历(xs)(计数)
    val text=Concat.transverse(xs)
    
    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, 2, 3, 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, List(a.toString + "Z")))
        (sum, text.reverse) === (10, List("1Z", "2Z","3Z", "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, text.reverse) === (10, List("1Z", "2Z","3Z", "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, text.reverse) === (10, List("1Z", "2Z","3Z", "4Z"))
      }
    }