scala学习笔记(3) -- for comprehension

scala并不支持一般的for循环,取而代之的是for comprehesion。scala通过丰富
的for comprehesion特性支持各种循环结构。
要使一个类支持for comprehesion很简单,不需要继承任何trait,相应的实现
map, filter, flatMap, foreach四个方法中的一个或多个即可。下面针对每种
语法解释一下。

scala 伪代码
  1. // 语法形式           
  2. for( val p <- e ) yield ee           
  3. // 对应的函数调用 -- map           
  4. e.map( p => ee )           
  5.           
  6. // 语法形式           
  7. for( val p <- e ) ee        
  8. // 对应的函数调用 -- foreach           
  9. e.foreach {  p => ee }           
  10.           
  11. // 语法形式           
  12. for( val p <- e; val pp <- ee ) yield eee        
  13. // 对应的函数调用 -- flatMap           
  14. e.flatMap( p => for(pp <- ee ) yield eee )           
  15.           
  16. // 语法形式           
  17. for( val p <- e; val pp <- ee ) eee        
  18. // 对应的函数调用 -- foreach           
  19. e.foreach( p => for( pp <- ee ) eee )           
  20.           
  21. // 语法形式           
  22. for ( val p <- e ) if g ...           
  23. // 对应的函数调用 -- filter           
  24. <- e.filter( ... => g )          

也就是说,任何一个类,只要实现了map方法(参数为一个函数),就可以使用 for (val v < - new class) yield v 的语法。如果再实现了filter方法,就可以使用 for(val v < - obj if guard) yield v 的语法,如果实现了flatMap方法,就可以使用复合的 for(val v1< -o1; val v2< -o2) yield o1 op o2这样的语法,如果实现了foreach方法,可以实现 for(val v< -obj){f} 的语法。

scala对for comprehension的支持是通过在编译期检查类的方法增加的,不需要象java那样显示地从Iterable方法派生,而且4个函数之中可以根据需要来实现,要灵活地多。

举几个简单的例子对比一下

scala 代码
  1. class ForIterClass {   
  2.   def map(f: int => int): List[int] = List( 123 )    
  3.   def foreach(f: int => Unit) = println("hello foreach")   
  4. }   
  5.   
  6. for( val p <- new ForIterClass) yield p   
  7. // 等价于   
  8. (new ForIterClass) map (p => p)   
  9.   
  10. for( val fc <- new ForIterClass ) println(fc)   
  11. // 等价于   
  12. (new ForIterClass) foreach (fc => println("hello foreach"))   
  13.   
  14. for { i <1 until n   
  15.       j <1 until i   
  16.       if isPrime(i+j)   
  17. } yield (i, j)   
  18. // 等价于   
  19. (1 until n)   
  20.     .flatMap {   
  21.       case i => (1 until i)   
  22.         .filter { j => isPrime(i+j) }   
  23.         .map { case j => (i, j) } }   

 

你可能感兴趣的:(scala,xml,F#,J#)