, play-iteratees scalaz-stream, , .
:
, :
class PStateM[Elem, Result](val receiveM: Option[Elem] => (Option[PStateM[Elem, Result]], Option[Result]))
P , M Monadic, monad - Option ( , Future teratee)
Option 2.
Option[Elem] , , None .
Option[PStateM[Elem, Result]] , .
, 2.:
class PState[Elem, Result](val receive: Elem => (PStateM[Elem, Result], Option[Result])) extends PStateM[Elem, Result]({
case Some(elem) => receive(elem) match {case (next, res) => (Some(next), res)}
case None => (None, None)
})
Nest , 3:
def process[Elem, Result](state: PStateM[Elem, Result], source: Stream[Elem]): Stream[Result] = source match {
case Stream() => state.receiveM(None)._2.toStream
case head
val (next, res) = state.receiveM(Some(head))
next match {
case None => res.toStream
case Some(nState) => res match {
case None => process(nState, tail)
case Some(res) => res
}
}
}
}
, match es, .
, . :
case class MapS[A, B](f: A => B) extends PState[A, B](elem => (MapS(f), Some(f(elem))))
case class FoldS[A, B](z: B, f: (B, A) => B) extends PStateM[A, B]({
case Some(elem) => (Some(FoldS(f(z, elem), f)), None)
case None => (None, Some(z))
})
case class FilterS[A](f: A => Boolean) extends PState[A, A](elem => (FilterS(f), Some(elem) filter f))
,
println(process(MapS[Int, Int](_ * 2), Stream.from(1)).take(10).toList)
println(process(FilterS[Int](_ % 2 == 1), Stream.from(1)).take(10).toList)
println(process(FoldS[Int, Long](0L, _ + _.toLong), 1 to 100000 toStream))
10 , 10 StackOverflowError
, . , . , , :
- node
count children- node -
count - 1
,
trait Node
case class Branch(elem: Int, children: IndexedSeq[Int]) extends Node
case class Leaf(elem: Int) extends Node
:
case class NodeElem() extends PState[Int, Node](elem => (NodeChildCnt(elem), None))
case class NodeChildCnt(elem: Int) extends PState[Int, Node]({
case 0 => (NodeElem(), Some(Leaf(elem)))
case count => (NodeChildElem(elem, count, IndexedSeq.empty), None)
})
case class NodeChildElem(elem: Int, count: Int, children: IndexedSeq[Int]) extends PStateM[Int, Node]({
case Some(child) =>
if (count > 1)
(Some(NodeChildElem(elem, count - 1, children :+ child)), None)
else (Some(NodeElem()), Some(Branch(elem, children :+ child)))
case None => (None, Some(Branch(elem, children)))
})
: NodeElem node , NodeChildCnt Leaf, 0 NodeChildElem , .
println(process(NodeElem, "1 2 2 3 2 2 4 5 3 0 4 0 5 4 6 7".split(' ').toStream.map(_.toInt)).toList)
5'th node:
List(Branch(1,Vector(2, 3)), Branch(2,Vector(4, 5)), Leaf(3), Leaf(4), Branch(5,Vector(6, 7)))