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中描述。它还涉及国家。我在手机上,否则我会提供链接 以下是链接:
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"))
}
}