Cartesian product traverse in scalaz

前端 未结 4 872
逝去的感伤
逝去的感伤 2021-02-10 03:06

In Eric Torreborre\'s blogpost on the paper Essence of the Iterator Pattern, he describes how the cartesian product of a traverse is also a traverse.

Can anyone show me

4条回答
  •  没有蜡笔的小新
    2021-02-10 03:44

    If I understand you correctly that what you are looking for should be described in the scala-seven branch example: WordCount. It also involves state. I'm on mobile otherwise I would provide link.

    Here's the links:

    • Scalaz 6
    • Scalaz 7

    HTH Andreas

    EDIT:

    Ok some more explanations. I think the fundamental problem of your questions is how to compose functions or therefor applicative. This can be achieved through the product method on applicative.

    https://github.com/scalaz/scalaz/blob/scalaz-seven/core/src/main/scala/scalaz/Applicative.scala#L46

    So you need to define applicative for your two functions shape and accum. Where accum would be modeled as a state applicative.

    If we look at this line form the example: val WordCount = StateT.stateMonad[Int].compose({type λ[α] = Int})#λ

    It creates an applicative which 'works' (sorry my poor wording) which state. Usually on traverse you have only the current element nothing more. But if you want to compute on previous computations you need state so this create an state-applicative which returns 1 for each element it traverses ( see Monoid[Int].applicative).

    Now to DO actually something we need to look at the atWordStart Method and you need to define a method which can work with the constructed WordCount applicative (using State)

    Here is another example from scalaz 6, which is more simple. I think its important to observe the initialValue and how the transform1 method does :

    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
      }
    }
    

    I remember now because the topic interested me too. I asked why eric in his blogpost did not provide the applicative product. He said he it gave up wrestling with the type signatures. Arround that time jason fixed the WordCount example for scalaz7 ( six example did not provide action counting word)

提交回复
热议问题