Programming in Scalaを読み始めた Chapter1-3
Chapter1はイントロ。Charpter2から本格的にはじまる。
まずはScalaのインストール
$ sudo port install scala
Scalaの起動とHello, world!など。すでに型推論が出てきている。
$ scala Welcome to Scala version 2.7.4.final (Java HotSpot(TM) Client VM, Java 1.5.0_19). Type in expressions to have them evaluated. Type :help for more information. scala> 1+2 res0: Int = 3 scala> res0*3 res1: Int = 9 scala> println("Hello, world!") Hello, world!
変数宣言の方法はvalとvarがある。valだとimmutable
scala> val msg="Hello, world!" msg: java.lang.String = Hello, world! scala> println(msg) Hello, world! scala> msg="hoge" <console>:5: error: reassignment to val msg="hoge" ^ scala> var hoge = "a" hoge: java.lang.String = a scala> hoge="b" hoge: java.lang.String = b
関数はdefで宣言。Unitはvoidみたいなもん。
scala> def max(x: Int, y: Int): Int = { | if(x>y)x | else y | } max: (Int,Int)Int scala> max(1,2) res5: Int = 2 scala> def greet() = println("Hello, world!") greet: ()Unit scala> greet Hello, world!
whileループとコマンドライン引数
$ cat echoargs.scala var i = 0 while(i<args.length) { if(i!=0) { print(" ") } print(args(i)) i += 1 } println() $ scala echoargs.scala Scala is even more fun Scala is even more fun
以下のような感じでも書ける
args.foreach(arg => println(arg))
args.foreach(println)
for(arg <- args) println(arg)
ここでChapter2終了。
Chapter3がはじまる。
Array(配列)。[0]じゃなくて(0)なのね。forの書き方が特殊ね。
$ cat greetStrings.scala val greetStrings = new Array[String](3) greetStrings(0) = "Hello" greetStrings(1) = ", " greetStrings(2) = "world!\n" for ( i <- 0 to 2) print(greetStrings(i)) $ scala greetStrings.scala Hello, world!
List。これもimmutable。:::で連結。::はcons
scala> List(1,2) ::: List(3,4) res10: List[Int] = List(1, 2, 3, 4) scala> 1::List(2, 3) res12: List[Int] = List(1, 2, 3) scala> 1::2::3::Nil res13: List[Int] = List(1, 2, 3)
タプル。これもimmutable。
scala> val tuple = (99, "Luftballons") tuple: (Int, java.lang.String) = (99,Luftballons) scala> tuple._1 res17: Int = 99 scala> tuple._2 res18: java.lang.String = Luftballons
ここまでがChapter3のStep9
Step10
Set。mutableとimmutableがあるらしい。
scala> import scala.collection.immutable.HashSet import scala.collection.immutable.HashSet scala> val hashSet = HashSet("Tomoatoes", "Chilies") hashSet: scala.collection.immutable.Set[java.lang.String] = Set(Chilies, Tomoatoes) scala> println(hashSet + "Coriander") Set(Coriander, Chilies, Tomoatoes) scala> Set("Boeing", "Airbus") res23: scala.collection.immutable.Set[java.lang.String] = Set(Boeing, Airbus)
Map。これもmutableとimmutableがあるらしい。
scala> import scala.collection.mutable.Map import scala.collection.mutable.Map scala> val treasureMap = Map[Int, String]() treasureMap: scala.collection.mutable.Map[Int,String] = Map() scala> treasureMap += (1 -> "Go to island.") scala> treasureMap += (2 -> "Find big X on ground.") scala> treasureMap += (3 -> "Dig.") scala> println(treasureMap(2)) Find big X on ground.
Step 11
scala> def formatArgs(args: Array[String]) = args.mkString("\n") formatArgs: (Array[String])String scala> val res = formatArgs(Array("zero", "one", "two")) res: String = zero one two scala> assert(res == "zero\none\ntwo") scala> assert(res == "zero\none\ntw") java.lang.AssertionError: assertion failed at scala.Predef$.assert(Predef.scala:87) at .<init>(<console>:7) at .<clinit>(<console>) at RequestResult$.<init>(<console>:3) at RequestResult$.<clinit>(<console>) at RequestResult$result(<console>) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.j...
Step12
IO処理なぞを。
$ cat countchars1.scala import scala.io.Source if(args.length>0) { for(line <- Source.fromFile(args(0)).getLines) print(line.length + " " + line) } else Console.err.println("Please enter filename") $ scala countchars1.scala countchars1.scala 23 import scala.io.Source 1 20 if(args.length>0) { 49 for(line <- Source.fromFile(args(0)).getLines) 36 print(line.length + " " + line) 2 } 5 else 47 Console.err.println("Please enter filename")
reduceLeftが関数型っぽいね。
$ cat countchars2.scala import scala.io.Source def widthOfLength(s: String) = s.length.toString.length if(args.length>0) { val lines = Source.fromFile(args(0)).getLines.toList val longuestLine = lines.reduceLeft( (a, b) => if(a.length > b.length) a else b ) val maxWidth = widthOfLength(longuestLine) for(line<-lines) { val numSpaces = maxWidth - widthOfLength(line) val padding = " " * numSpaces print(padding + line.length + " | " + line) } } else Console.err.println("Please enter filename") $ scala countchars2.scala countchars2.scala 23 | import scala.io.Source 1 | 56 | def widthOfLength(s: String) = s.length.toString.length 1 | 20 | if(args.length>0) { 55 | val lines = Source.fromFile(args(0)).getLines.toList 1 | 39 | val longuestLine = lines.reduceLeft( 47 | (a, b) => if(a.length > b.length) a else b 4 | ) 1 | 45 | val maxWidth = widthOfLength(longuestLine) 1 | 21 | for(line<-lines) { 51 | val numSpaces = maxWidth - widthOfLength(line) 34 | val padding = " " * numSpaces 48 | print(padding + line.length + " | " + line) 4 | } 2 | } 5 | else 47 | Console.err.println("Please enter filename")