2010-12-30 12 views
12

List.zipWithIndex के व्यवहार की नकल करने के लिए मैं State का उपयोग कैसे करूं? क्या मैं (जो काम नहीं करता है) के साथ आए हैं अब तक है:बेसिक स्कालज़ राज्य प्रश्न

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 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 (और, यदि हां, तो क्या typeclasses की आवश्यकता है?)

संपादित 2 - मैं अब, यह सामान्यीकृत है थोड़ा 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)} }) 
} 

या बहुत समान:

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

उत्तर

9
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 

राज्य के साथ traversing के बारे में अधिक के लिए The Essence of the Iterator Pattern देखें।

+0

और मैं वहां था, सभी चालाक महसूस कर रहा था –