scala - 基本 Scalaz 状态问题

标签 scala functional-programming scalaz state-monad

我如何使用 State模仿 List.zipWithIndex 的行为?到目前为止我想出的(不起作用)是:

def numberSA[A](list : List[A]) : State[Int, List[(A, Int)]] = list match {
  case x :: xs => (init[Int] <* modify((_:Int) + 1)) map { s : Int => (x -> s) :: (numberSA(xs) ! s) }
  case Nil     => state( (i : Int) => i -> nil[(A, Int)] )
}

这非常松散地基于 state example .正如我所说,它不起作用:
scala> res4
res5: List[java.lang.String] = List(one, two, three)

scala> numberSA(res4) ! 1
res6: List[(String, Int)] = List((one,1), (two,1), (three,1))

我可以通过更改 case 语句的一行来使其工作:
case x :: xs => (init[Int]) map { s : Int => (x -> s) :: (numberSA(xs) ! (s + 1)) }

但这只是感觉不对。任何人都可以帮忙吗?

编辑 - 更多的玩耍让我想到了这个
def numberSA[A](list : List[A]) : State[Int, List[(A, Int)]] = {
  def single(a : A) : State[Int, List[(A, Int)]] = (init[Int] <* modify((_ : Int) + 1)) map { s : Int => List(a -> s) }
  list match {
    case Nil     => state( (_ : Int) -> nil[(A, Int)] )
    case x :: xs => (single(x) <**> numberSA(xs)) { _ ::: _ }
  }
}

可以改进吗?是否可以推广到除 List 以外的容器? (如果需要,需要什么类型类?)

编辑 2 - 我现在已经概括了它,虽然有点笨拙
def index[M[_], A](ma : M[A])
      (implicit pure : Pure[M], empty : Empty[M], semigroup : Semigroup[M[(A, Int)]], foldable : Foldable[M]) 
      : State[Int, M[(A, Int)]] = {
  def single(a : A) : State[Int, M[(A, Int)]] = (init[Int] <* modify((_ : Int) + 1)) map { s : Int => pure.pure(a -> s) }
  foldable.foldLeft(ma, state( (_ : Int) -> empty.empty[(A, Int)] ), { (s : State[Int, M[(A, Int)]],a : A) => (s <**> single(a)) { (x,y) => semigroup.append(x,y)}  } )
}

或者非常相似的:
def index[M[_] : Pure : Empty : Plus : Foldable, A](ma : M[A]) 
     : State[Int, M[(A, Int)]] = {
  import Predef.{implicitly => ??}
  def single(a : A) : State[Int, M[(A, Int)]] = (init[Int] <* modify((_ : Int) + 1)) map { s : Int => ??[Pure[M]].pure(a -> s) }
  ??[Foldable[M]].foldLeft(ma, state( (_ : Int) -> ??[Empty[M]].empty[(A, Int)] ), { (s : State[Int, M[(A, Int)]],a : A) => (s <**> single(a)) { (x,y) => ??[Plus[M]].plus(x,y)}  } )
}

最佳答案

def index[M[_]:Traverse, A](m: M[A]) =
  m.traverse[({type λ[x] = State[Int,x]})#λ, (A, Int)](a =>
    state(i => (i + 1, (a, i)))) ! 0

甚至...
def index[M[_]:Traverse, A](m: M[A]) =
  m.traverse[({type λ[x] = State[Int,x]})#λ, (A, Int)](a =>
    (Lens.self[Int] += 1) map ((a, _)) ! -1

The Essence of the Iterator Pattern有关使用 State 遍历的更多信息。

关于scala - 基本 Scalaz 状态问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4562850/

相关文章:

scala - Spark Scala 数据帧查找最大值

haskell - 无法将类型 `h' 与 `String' 匹配

functional-programming - SICP DrScheme 中的哪种语言?

scala - scalaz 中的类型类和继承

scala - Kleisli 是仿函数、应用函数还是单子(monad)?

scala - 如何将 ADT 列表分成其变体?

scala - Scala 中的列表 - 加冒号与双冒号(+: vs::)

scala - 为什么 Spark/Scala 编译器无法在 RDD[Map[Int, Int]] 上找到 toDF?

java - 在简单的 Scala 应用程序中嵌入终端窗口

python - 有人可以向我解释函数对象和闭包之间的区别吗