2. Iteratee
структуры данных (Iteratee, Enumerator, Iteratee)
которые определяют состояние процессинга
потока.
●
Разобраться что это такое
●
Построить 'с нуля' подобные интерфейсы
●
Язык scala как псевдокод
●
Показать использование как OO- паттерна
https://github.com/rssh/iteratee-article
3. Iteratee
Eng. (ee) => rus (уемый)
Trainee – тот кого тренируют
Iteratee – то, что итерируют
8. Fold - свертка
1. Отредуцировать все элементы коллекции
с помощью какой-то операции
Collection[A]: def foldLeft[S](s0:S)((S,A)=>S)
(1 to 10) foldLeft ( _ + _)
2. Произвести разбор случаев и вернуть значение
одного типа:
Either[A,B]: def fold[X](fa: A=>X, fb: B=>X)
Left(“problem x”).fold[String]( “error:” + _ ,
“ok:” + _ )
9. Fold - свертка
1. Отредуцировать все элементы коллекции
с помощью какой-то операции
Collection[A]: def foldLeft[S](s0:S)((S,A)=>S)
(1 to 10) foldLeft ( _ + _)
2. Произвести разбор случаев и вернуть
значение одного типа:
Either[A,B]: def fold[X](fa: A=>X, fb: B=>X)
Left(“problem x”).fold[String]( “error:” + _ ,
“ok:” + _ )
10. Коллекция – это то, что дает нам fold
trait Iteratee1[A,S]
{
def fold( whenNext: (S, A) => S,
whenEof: S => S)
}
11. Коллекция – это то что, дает нам fold
trait Iteratee1[A,S]
{
def fold( whenNext: (S, A) => S,
whenEof: S => S)
}
def run(input,state) =
if (!input.isEmpty && state.isDone) {
state = whenNext(state, input.readElement)
run(input, state)
} else {
whenEof(state)
}
12. Коллекция – это то, что дает нам fold
trait Iteratee1[A,S]
{
def fold( whenNext: (S, A) => S,
whenEof: S => S)
}
def run(input,state) =
if (!input.isEmpty && !state.isDone) {
state = whenNext(state, input.readElement)
run(input, state)
} else {
whenEof(state)
}
22. trait Iteratee4[A,S]
{
def fold[B](whenNext: (A => Iteratee[A,S]) => B),
whenEnd: S => B)
}
Секунду – давайте введем еще одно преобразование:
В текущем интерфейса
Введем условное получение следующего элемента
23. trait Iteratee5[A,S]
{
def fold[B](whenNext: (Input[A]Input[A] => Iteratee[A,S]) => B),
whenEnd: S => B)
}
sealed trait Input[+A]
case class El[+A] extends Input[A]
case object Eol extends Input[Nothing]
+ ....
37. Compose
Iteratee
(принять заголовок пакета, а потом сам пакет)
def compose[A,S](frs: Iteratee[A,S], snd:Iteratee[A,S]) =
new Iteratee[A,S] {
def fold[B](onNext: (Input[A] => Iteratee[A,S])=>B,
onDone: S => B) =
frs.fold( step => onNext(compose(step(_),snd)),
s => snd.fold(onNext,onDone)
)
}
Первое намерение:
38. Compose
Iteratee -- problems
def compose[A,S](x: MyIteratee[A,S], y:MyIteratee[A,S]) =
new MyIteratee[A,S] {
def fold[B](onNext: (Input[A] => MyIteratee[A,S])=>B,
onDone: S => B) =
frs.fold( step => onNext(compose(step(_),snd)),
s => snd.fold(onNextonNext,onDone)
)
}
Теряем символ
39. Iteratee - уточнение сигнатуры
trait Iteratee5[A,S]
{
def fold[B](whenNext: (Input[A] => Iteratee[A,S]) => B),
whenEnd: S => B)
}
old
40. Iteratee - уточнение сигнатуры
trait Iteratee5[A,S]
{
def fold[B](whenNext: (Input[A] => Iteratee[A,S]) => B),
whenEnd: S => B)
}
old
48. case class MapEnumeratee[From,To](f:From => To)
extends Enumeratee[From,To]
{
def applyOn[S](it: Iteratee[To,S]): Iteratee[From, Iteratee[To,S]]=
new Iteratee[From, Iteratee[To,S]] {
def fold[B](onNext, onDone) =
it.fold(
step => onNext( x => applyOn(step(x map f)) ),
(in, s) => onDone(Input.Empty,Done(in,s))
)
}
}
Enumeratee: пример
Доопределить map на Input: Input.El(x) map (f) = Input.El(f(x))
Input.Eof map f = Input.Eof
Input.Empy map f = Input.Empty
49. Итого:
Абстракции генерирования и потоковой обработки:
Iteratee -- конечное звено обработки элементов (fold)
Enumerator – генератор элементов (apply)
Enumeratee -- преобразователь (transform)
Строить нетривиальные процессы потоковой обработки
Комбинировать в функциональном стиле
50. FP/OOP
Можно использовать как OOP паттерн
Fold не нужен
trait OOIteratee[A,S]
{
def next(inp: Input[A]): OOIteratee[A,S]
def isDone: Boolean
}
53. Использование в реальной жизни
Scala - обработка потоков в play
http://www.playframework.com/documentation/2.1.1/Iteratees
C# -- Reactice Extensions (Rx)
http://msdn.microsoft.com/en-us/data/gg577609.aspx
Haskell -- Iteratee IO.
http://www.haskell.org/haskellwiki/Iteratee_I/O