際際滷

際際滷Share a Scribd company logo
ENUMERATOR &> PLAY 
|>>> 
ITERATEE 
PLAY MEETUP HAMBURG, 6.10.2014 
MARKUS.KLINK@INO.IO 
@JOHEINZ
GIT CLONE HTTPS:// 
GITHUB.COM/INOIO/ 
ITERATEE-TALK 
! 
! 
! 
SBT ~RUN
SOME LINKS: 
PLAY DOCUMENTATION 
(MORE OR LESS INCOMPREHENSIBLE) 
HTTP://MANDUBIAN.COM/2012/08/27/UNDERSTANDING-PLAY2-ITERATEES-FOR-NORMAL-HUMANS/ 
(ADDRESSES SOME OF THE SHORTCOMINGS) 
HTTPS://JAZZY.ID.AU/2012/11/06/ITERATEES_FOR_IMPERATIVE_PROGRAMMERS.HTML 
(YEAH, MORE INFO) 
ACTIVATOR TEMPLATE (SEARCH FOR ITERATEES) 
HTTPS://GITHUB.COM/JROPER/PLAY-ITERATEES-EXTRAS 
HTTPS://WWW.PLAYFRAMEWORK.COM/DOCUMENTATION/2.3.X/API/SCALA/INDEX.HTML#PLAY.API.LIBS.3
DATA PROCESSING 
PIPELINE 
HARPER & CHRISTY DOING IT PURELY FUNCTIONAL
REACTIVE STREAMS ARE 
TWO WAY, IT'S NOT JUST 
YOU, THE STREAM 
CONSUMER THAT IS 
REACTING TO INPUT, THE 
STREAM PRODUCER MUST 
REACT TO YOU BEING READY 
FOR INPUT. James Roper
OTHER 
IMPLEMENTATIONS 
SCALAZ STREAM 
SCALAZ ITERATEES (OUTDATED)
THE IMPORTANT BITS 
ENUMERATOR[A] 
PRODUCES VALUES OF TYPE A 
MONAD (COMPOSABLE WITH A CONTEXT) 
MANY UTILITIES IN COMPANION OBJECT 
SMART 
!
ENUMERATOR API 
Enumerator.apply[A](a: A*) : Enumerator[A] 
Enumerator.enumerate[A](a: TraversableOnce[A]) : Enumerator[A] 
Enumerator.generateM[A](e : => Future[Option[A]]) : Enumerator[A] 
ALL THE FLATMAP GOODIES + GIVEN AN ENUMERATOR[E] 
|>>[A](i: Iteratee[E, A]): Future[Iteratee[E, A]] 
|>>>[A](i: Iteratee[E, A]): Future[A] 
&>[To](enumeratee: Enumeratee[E, To]): Enumerator[To]
THE IMPORTANT BITS 
ENUMERATEE[A,B] 
TRANSFORMS VALUES FROM A => B 
! 
MANY UTILITIES IN COMPANION OBJECT 
! 
NOT AS DUMP AS I THOUGHT
THE IMPORTANT BITS 
ITERATEE[A,B] 
CONSUMES INPUT ELEMENTS OF TYPE A AND OUTPUTS B 
MONAD (COMPOSABLE WITH A CONTEXT) 
SUPER SMART 
! 
! 
! 
INPUT IS EITHER: 
A.EMPTY: INPUT.EMPTY 
B.EOF: INPUT.EOF 
C.OR CONTAINS AN A: INPUT.EL(A) 
! 
ITERATEE STATE IS EITHER: 
A. DONE CONSUMING WITH A RESULT 
B. READY TO CONSUME MORE CONT 
C. OR IN ERROR STATE
ITERATEE API 
ALL THE FLATMAP GOODIES + GIVEN AN ITERATEE[E,A] 
run: Future[A] 
COMMON PATTERN TO BUILD AN ITERATEE: 
def myIteratee(x: AllTheStateINeed, 
oForNothing: O) : Iterator[I,O] = Cont { 
case Input.EOF => Done(oForNothing, Input.EOF) 
case Input.Empty => myIterator(x, oForNothing) 
case in@Input(i) => // be done with o || change state and recurse 
// create an Error with Error(message, in) 
!
HINT 
WHEN USING DONE, 
ALWAYS SPECIFY THE 
NEXT INPUT EXPLICITLY 
(DEFAULTS TO 
INPUT.EMPTY)
ENUMERATEE ><> 
ENUMERATOR ENUMERATEE ITERATEE 
&> &>> 
ENUMERATOR ITERATEE 
ENUMERATEE API
ENUMERATEE API 
THINK OF AN ENUMERATOR AS A KIND OF 
TRANSFORMER, ADAPTER AND COLLECTION: 
TAKE, TAKEWHILE, 
GROUPED, 
DROP, DROPWHILE, 
FILTER, FILTERNOT, MAP,
val processElement: Iteratee[Byte, Element] = for { 
_ <- findLeftBrace 
string <- consumeUntilRightBrace 
element <- { 
safeParse(string) match { 
case Success(element) => Done[Byte, Element](element) 
case Failure(_) => Error[Byte](s"$string not a valid element", Input.EOF) 
} 
} 
} yield element 
COMPOSE 
ITERATEES & ENUMERATORS 
USING FOR 
COMPREHENSIONS
IN PRINCIPLE ITS EASY, 
IT IS JUST POWERFUL 
CODE

More Related Content

Iteratees/Enumerators in Play

  • 1. ENUMERATOR &> PLAY |>>> ITERATEE PLAY MEETUP HAMBURG, 6.10.2014 MARKUS.KLINK@INO.IO @JOHEINZ
  • 2. GIT CLONE HTTPS:// GITHUB.COM/INOIO/ ITERATEE-TALK ! ! ! SBT ~RUN
  • 3. SOME LINKS: PLAY DOCUMENTATION (MORE OR LESS INCOMPREHENSIBLE) HTTP://MANDUBIAN.COM/2012/08/27/UNDERSTANDING-PLAY2-ITERATEES-FOR-NORMAL-HUMANS/ (ADDRESSES SOME OF THE SHORTCOMINGS) HTTPS://JAZZY.ID.AU/2012/11/06/ITERATEES_FOR_IMPERATIVE_PROGRAMMERS.HTML (YEAH, MORE INFO) ACTIVATOR TEMPLATE (SEARCH FOR ITERATEES) HTTPS://GITHUB.COM/JROPER/PLAY-ITERATEES-EXTRAS HTTPS://WWW.PLAYFRAMEWORK.COM/DOCUMENTATION/2.3.X/API/SCALA/INDEX.HTML#PLAY.API.LIBS.3
  • 4. DATA PROCESSING PIPELINE HARPER & CHRISTY DOING IT PURELY FUNCTIONAL
  • 5. REACTIVE STREAMS ARE TWO WAY, IT'S NOT JUST YOU, THE STREAM CONSUMER THAT IS REACTING TO INPUT, THE STREAM PRODUCER MUST REACT TO YOU BEING READY FOR INPUT. James Roper
  • 6. OTHER IMPLEMENTATIONS SCALAZ STREAM SCALAZ ITERATEES (OUTDATED)
  • 7. THE IMPORTANT BITS ENUMERATOR[A] PRODUCES VALUES OF TYPE A MONAD (COMPOSABLE WITH A CONTEXT) MANY UTILITIES IN COMPANION OBJECT SMART !
  • 8. ENUMERATOR API Enumerator.apply[A](a: A*) : Enumerator[A] Enumerator.enumerate[A](a: TraversableOnce[A]) : Enumerator[A] Enumerator.generateM[A](e : => Future[Option[A]]) : Enumerator[A] ALL THE FLATMAP GOODIES + GIVEN AN ENUMERATOR[E] |>>[A](i: Iteratee[E, A]): Future[Iteratee[E, A]] |>>>[A](i: Iteratee[E, A]): Future[A] &>[To](enumeratee: Enumeratee[E, To]): Enumerator[To]
  • 9. THE IMPORTANT BITS ENUMERATEE[A,B] TRANSFORMS VALUES FROM A => B ! MANY UTILITIES IN COMPANION OBJECT ! NOT AS DUMP AS I THOUGHT
  • 10. THE IMPORTANT BITS ITERATEE[A,B] CONSUMES INPUT ELEMENTS OF TYPE A AND OUTPUTS B MONAD (COMPOSABLE WITH A CONTEXT) SUPER SMART ! ! ! INPUT IS EITHER: A.EMPTY: INPUT.EMPTY B.EOF: INPUT.EOF C.OR CONTAINS AN A: INPUT.EL(A) ! ITERATEE STATE IS EITHER: A. DONE CONSUMING WITH A RESULT B. READY TO CONSUME MORE CONT C. OR IN ERROR STATE
  • 11. ITERATEE API ALL THE FLATMAP GOODIES + GIVEN AN ITERATEE[E,A] run: Future[A] COMMON PATTERN TO BUILD AN ITERATEE: def myIteratee(x: AllTheStateINeed, oForNothing: O) : Iterator[I,O] = Cont { case Input.EOF => Done(oForNothing, Input.EOF) case Input.Empty => myIterator(x, oForNothing) case in@Input(i) => // be done with o || change state and recurse // create an Error with Error(message, in) !
  • 12. HINT WHEN USING DONE, ALWAYS SPECIFY THE NEXT INPUT EXPLICITLY (DEFAULTS TO INPUT.EMPTY)
  • 13. ENUMERATEE ><> ENUMERATOR ENUMERATEE ITERATEE &> &>> ENUMERATOR ITERATEE ENUMERATEE API
  • 14. ENUMERATEE API THINK OF AN ENUMERATOR AS A KIND OF TRANSFORMER, ADAPTER AND COLLECTION: TAKE, TAKEWHILE, GROUPED, DROP, DROPWHILE, FILTER, FILTERNOT, MAP,
  • 15. val processElement: Iteratee[Byte, Element] = for { _ <- findLeftBrace string <- consumeUntilRightBrace element <- { safeParse(string) match { case Success(element) => Done[Byte, Element](element) case Failure(_) => Error[Byte](s"$string not a valid element", Input.EOF) } } } yield element COMPOSE ITERATEES & ENUMERATORS USING FOR COMPREHENSIONS
  • 16. IN PRINCIPLE ITS EASY, IT IS JUST POWERFUL CODE