@MiloXia
2016-01-13T06:48:10.000000Z
字数 2493
阅读 2004
scala 函数式编程
逆Monad, 定义:
//A comonad is the same thing as a monad, only backwardstrait Comonad[W[_]] extends Functor[W] {def counit[A](w: W[A]): A //又名extractdef duplicate[A](wa: W[A]): W[W[A]]}
是flatMap的逆向
(W[A] -> B) -> W[A] -> W[B]
//参数与flatMap是反的,接W[A] -> A的函数,comonads的组合又叫coKleisli,逆Kleislidef extend[B](f: Coreader[R,A] => B): Coreader[R,B] =duplicate map f
等价于Id Monad
case class Id[A](a: A) {def map[B](f: A => B): Id[B] = Id(f(a))def counit: A = adef duplicate: Id[Id[A]] = Id(this)}
语义:当R准备好时(最后调用run传入),从R中读取出A
composition的语义:只能看到部分操作的结构A,用于后续的(map/flatMap)操作
case class Reader[R,A](run: R => A)def ask[R]: Reader[R,R] = Reader(r => r) //unitdef join[R,A](r: Reader[R,Reader[R,A]]) =Reader((c:R) => r.run(c).run(c))
语义:
we don’t have to pretend to have an R value. It’s just right there and we can look at it.
不需要提供(也就是run方法)R一开始就提供好了,直接取出值
composition的语义:获得全部的上下文W[A],用于后续的(extend)操作
The name extend refers to the fact that it takes a “local” computation that operates on some structure and “extends” that to a “global” computation that operates on all substructures of the larger structure.
case class Coreader[R,A](extract: A, ask: R) {def map[B](f: A => B): Coreader[R,B] = Coreader(f(extract), ask)def duplicate: Coreader[R, Coreader[R, A]] =Coreader(this, ask)def extend[B](f: Coreader[R,A] => B): Coreader[R,B] =duplicate map f}def coreaderComonad[R]: Comonad[Coreader[R,?]] =new Comonad[Coreader[R,?]] {def map[A,B](c: Coreader[R,A])(f: A => B) = c map fdef counit[A](c: Coreader[R,A]) = c.extractdef duplicate(c: Coreader[R,A]) = c.duplicate}
语义:往W中append A (W已经准备好,不需要run方法)
composition的语义:只能看到部分操作的结构W,用于后续的(map/flatMap)操作
case class Writer[W,A](value: A, log: W)def tell[W,A](w: W): Writer[W,Unit] = Writer((), w)def join[W:Monoid,A](w: Writer[W,Writer[W,A]]) =Writer(w.value.value, Monoid[W].append(w.log, w.value.log))def unit[W:Monoid,A](a: A) = Writer(a, Monoid[W].zero)
语义:
But instead of keeping the log always available to be appended to, it uses the same trick as the reader monad by building up an operation that gets executed once a log becomes available
当W准备好时(最后调用tell传入),从W中写入(看duplicate方法)
composition的语义:获得全部的上下文W[A],用于后续的(extend)操作
case class Cowriter[W:Monoid,A](tell: W => A) {def map[B](f: A => B): Cowriter[W,B] = Cowriter(tell andThen f)def extract = tell(Monoid[W].zero)def duplicate: Cowriter[W, Cowriter[W, A]] =Cowriter(w1 => Cowriter(w2 => tell(Monoid[W].append(w1, w2))))def extend[B](f: Cowriter[W,A] => B): Cowriter[W,B] =duplicate map f}
语义上Comonad与Monad是逆反的