基本斯卡拉州议题 [英] Basic Scalaz State question

查看:80
本文介绍了基本斯卡拉州议题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  def numberSA [A](list:List [A]):State [Int,List [(A,Int)]] =列表匹配{
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)])
}

这非常基于状态示例。正如我所说,它不起作用:

  scala> res4 
res5:List [java.lang.String] =列表(一,二,三)

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 =>列表(a - > s)}
列表匹配{
case Nil => state((_:Int) - > nil [(A,Int)])
case x :: xs => (single(x)** numberSA(xs)){_ ::: _}
}
}

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



编辑2 - 现在我已经概括了它,尽管有点笨拙

 <$ c [c],def index [M [_],A](ma:M [A])
(隐式纯:Pure [M],empty:空[M],半群:Semigroup [M [ ,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 => (p,int) - > empty.mpty [(A,Int)]),{(s:State [Int ,M((A,I))],a:A)=>(s **单(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 => (a:A):State [Int,M [(A,Int)]] =(init [Int]< * modify((_:Int)+ 1))map { s:Int =>折叠[M]]。foldLeft(ma,state((_:Int) - > [空[[]]纯净的(a-> s)}
[ (A,Int)]],空([A,Int)]),{(s:State [Int,M [(A,Int)]],a:A)=>(s< )){(x,y)=> ?? [Plus [M]]。plus(x,y)}})
}


解决方案

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

甚至...

 def index [M [_]:遍历,A](m:M [A])= 
m.traverse [({typeλ[x] = State [Int, (a,)))(a =>
(Lens.self [Int] + = 1)map((a,_))!-1
code>

请参阅迭代器模式的本质,了解更多关于状态遍历的​​信息。


How do I use State to mimic the behaviour of List.zipWithIndex? What I have come up with so far (which doesn't work) is:

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

This is based very loosely on the state example. As I said, it does not work:

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

I can get it to work by changing a line of the case statement:

case x :: xs => (init[Int]) map { s : Int => (x -> s) :: (numberSA(xs) ! (s + 1)) }

But this just feels wrong. Can anyone help?

EDIT - more playing around has got me to this

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)) { _ ::: _ }
  }
}

Can it be improved? Can it be generalized to containers other than List (and, if so, what typeclasses are needed?)

EDIT 2 - I have now generalized it, albeit a bit clunkily

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

Or the very similar:

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

Or even...

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

See The Essence of the Iterator Pattern for more on traversing with State.

这篇关于基本斯卡拉州议题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆