设为首页 加入收藏

TOP

Scalaz(13)- Monad:Writer - some kind of logger(三)
2017-10-10 12:13:31 】 浏览:6332
Tags:Scalaz Monad Writer some kind logger
red String 'Result'
" 5 } yield c + (a * b).shows //> res7: scalaz.WriterT[scalaz.Id.Id,String,String] = WriterT((Entered Int 3 En 6 //| tered Int 4 Entered String 'Result',Result:12))

如果A是高阶类型如List[T]的话,还能使用吗:

1 for {
2  la <- List(1,2,3) set Vector("Entered List(1,2,3)")
3  lb <- List(4,5) set Vector("Entered List(4,5)")
4  lc <- List(6) set Vector("Entered List(6)")
5 } yield (la |@| lb |@| lc) {_ + _ + _}            //> res1: scalaz.WriterT[scalaz.Id.Id,scala.collection.immutable.Vector[String]
6                                                   //| ,List[Int]] = WriterT((Vector(Entered List(1,2,3), Entered List(4,5), Enter
7                                                   //| ed List(6)),List(11, 12, 12, 13, 13, 14)))

的确没有问题。

那个gcd例子还是挺有代表性的,我们用Writer来运算和跟踪gcd运算:

 1 def gcd(a: Int, b: Int): Writer[Vector[String],Int] =
 2   if (b == 0 ) for {  3       _ <- Vector("Finished at "+a.shows).tell  4   } yield a  5   else
 6    Vector(a.shows+" mod "+b.shows+" = "+(a % b).shows).tell >>= {_ => gcd(b,a % b)}  7                                                   //> gcd: (a: Int, b: Int)scalaz.Writer[Vector[String],Int]
 8 
 9 gcd(8,3)                                          //> res8: scalaz.Writer[Vector[String],Int] = WriterT((Vector(8 mod 3 = 2, 3 mo 10                                                   //| d 2 = 1, 2 mod 1 = 0, Finished at 1),1))
11 gcd(16,4)                                         //> res9: scalaz.Writer[Vector[String],Int] = WriterT((Vector(16 mod 4 = 0, Fin 12                                                   //| ished at 4),4))

在维护跟踪记录(logging)时使用Vector会比List更高效。我们来证明一下:

 1 def listLogCount(c: Int): Writer[List[String],Unit] = {  2  @annotation.tailrec  3   def countDown(c: Int, w: Writer[List[String],Unit]): Writer[List[String],Unit] = c match {  4       case 0 => w >>= {_ => List("0").tell }  5       case x => countDown(x-1, w >>= {_ => List(x.shows).tell })  6  }  7   val t0 = System.currentTimeMillis  8   val r = countDown(c,List[String]().tell)  9   val t1 = System.currentTimeMillis 10   r >>= {_ => List((t1 -t0).shows+"msec").tell } 11 }                                                 //> listLogCount: (c: Int)scalaz.Writer[List[String],Unit]
12 def vectorLogCount(c: Int): Writer[Vector[String],Unit] = { 13  @annotation.tailrec 14   def countDown(c: Int, w: Writer[Vector[String],Unit]): Writer[Vector[String],Unit] = c match { 15       case 0 => w >>= {_ => Vector("0").tell } 16       case x => countDown(x-1, w >>= {_ => Vector(x.shows).tell }) 17  } 18   val t0 = System.currentTimeMillis 19   val r = countDown(c,Vector[String]().tell) 20   val t1 = System.currentTimeMillis 21   r >>= {_ => Vector((t1 -t0).shows+"msec").tell } 22 }                                                 //> vectorLogCount: (c: Int)scalaz.Writer[Vector[String],Unit]
23 
24 (listLogCount(10000).run)._1.last                 //> res10: String = 361msec
25 (vectorLogCount(10000).run)._1.last               //> res11: String = 49msec

看,listLogCount(10000)用了361msec

vectorLogCount(10000)只用了49msec,快了8,9倍呢。

 

首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Scalaz(12)- Monad:再述述fla.. 下一篇Scalaz(14)- Monad:函数组合..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目