Cartesian movement of a product in a scalar

Eric Torrebarra's blog blog on paper The essence of the iterator pattern , he describes how the Cartesian product of the traverse is also a traverse.

Can someone show me an example of this using the scalaz library , as I cannot figure it out. Let's say the problem is that with a List[Int] I want to provide both:

  • Sum Int Items in a List
  • A List[String] whose elements are created by appending "Z" to the string representation Int s

My understanding is that I can do this with traverse , but in a way that only really crosses my structure once, unlike this solution:

 val xs = List(1, 2, 3, 4) val (sum, strings) = (xs.sum, xs map (_.toString + "Z")) 

NOTE 1 I know that there are other ways to do this, and that I do not need a traverse for this example, and even the simplest way to solve it is not even required. I am, however, trying to understand the course, so I'm really looking for the answer to the question, as indicated


EDIT - thanks to the missingfactor below to show how to do this using State . I guess I want to know how I can make two independent calculations. For instance; my functions are as follows:

 val shape = (_ : List[Int]) map (_.toString + "Z") val accum = (_ : List[Int]).sum 

I want these accumulation mechanisms to be independent of each other, and then choose whether to go through my List[Int] using one or both of them. I presented some code a bit like this:

 xs traverse shape //A List[String] xs traverse accum //An Int xs traverse (shape <x> accum) //The pair (List[String], Int) 

Eric implies that this is possible, but I don’t understand how to do it. Those. I don’t see how to define shape and accum in such a way that they can be composed, and how to compose them.

NOTE 2 that shape and accum should not literally be functions with signatures, as indicated above. These are expressions that are of the type needed to perform the workarounds described above.

+5
source share
4 answers

I add my own answer based on Jason one to show different ways of going through the list:

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

I think the last example shows that you are after: 2 independently defined functions that can be composed to make only one workaround.

+4
source

Debashish Ghosh wrote a good post on this topic. Based on the code in this post:

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

Edit:

You have two functions List[A] => B and List[A] => C , and you want to use the function List[A] => (B, C) . Why &&& . However, this will not work. I can’t imagine how to use loops for such a case.

Fwiw, code:

 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) 

Edit 2:

If you have the functions A => B and A => C , you can combine them into A => (B, C) with &&& . Now, if B : Monoid and C : Monoid , you can use foldMap to get List[A] => (B, C) . This will make the material in one cycle.

the code:

 scala> val f: Int => Int = identity f: Int => Int = <function1> scala> val g: Int => List[String] = i => List(i.toString + "Z") g: Int => List[String] = <function1> scala> List(1, 2, 3, 4).foldMap(f &&& g) res95: (Int, List[String]) = (10,List(1Z, 2Z, 3Z, 4Z)) 

Final editing: (I swear I am not editing it again.)

Since these concepts originate in Haskell, I thought it would be a good idea to republish this question in the Haskell tag, and I did. The answer there seems to be consistent with what I said in this thread. Hôpe it helps.

+3
source

You don’t see a big victory here, because you simply advertise simple monoliths in Applicatives so that you merge them together.

 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") 

You can also use Monoid[(Int, List[String])] for the indicated problem:

 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") 

Everything becomes more interesting if one of the effects that you want to go through is a non-trivial application, such as State .

+3
source

If you correctly understood that what you are looking for should be described in the scala -sevent branch: WordCount example. It is also condition related. I am on a mobile phone, otherwise I would provide a link.

Here are the links:

Hth Andreas

EDIT:

Well a few more explanations. I think the main problem of your questions is how to compose functions or their application. This can be achieved using the product method of use.

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

So, you need to determine the applicative form and accuracy for your two functions. Where accumulation will be modeled as a government application.

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

It creates an applicative that "works" (sorry for my poor wording). Usually on the traverse you only have the current item. But if you want to calculate the previous calculations, you need to specify so that it creates a state application that returns 1 for each element to be moved (see Monoid [Int] .applicative).

Now, to really do something, we need to look at the atWordStart method, and you need to define a method that can work with the built-in WordCount application (using state)

Here is another example from scalaz 6, which is simpler. I think it is important to observe the initialValue and how the transform1 method works:

 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, because the topic interested me too. I asked why eric did not provide an applicative product on my blog. He said that he refused to fight with the type of signatures. Around that time, Jason fixed the WordCount example for scalaz7 (six examples do not indicate the word action count)

+2
source

Source: https://habr.com/ru/post/907927/


All Articles