Scalaçãªèãæ¹ - Scalaãã¨ã£ã¤ãã«ããã¨æã£ã¦ãã人ã¸
Javaãªäººããè¦ãã¨ããScalaã£ã¦é£ãããã£ã¦ã¤ã¡ã¼ã¸ãããã¾ããã俺ãæåã¯ããæã£ã¦ã¾ãããä»ãã§ããã©ã
ã§ãèãã¦ã¿ããã§ãããä½ãé£ããã£ã¦èãæ¹ã»ã¤ãã£ãªã ã«ãªãã¿ããªãã®ãåå ãã¨æã£ããã§ãã
ããã§ã¯ã俺ãä»ã¾ã§Scalaããã£ã¦ãã¦å¾ãèãæ¹ãç´¹ä»ãã¾ãããScalaãã¡ãã£ã¨ãã£ã¦ã¿ããã ãã©ãã¨ã£ã¤ãã«ããã¦â¦ãã¨æããã¦ããæ¹ã¯ããã²ãä¸èªãã ããã
åèè³æ:
Scala入門 - Scalaで書きはじめたJava使い向け - Scala勉強会@東北
Dropbox - 404
ç¥ã¯è¨ããããããªã¹ããããã
Lisperã¯ããªã¹ããã©ãä½ãããã¾ãèãããããã§ããé©åãªãªã¹ããåºæ¥ãããããã°ã©ã ã¯ããã§ãããåç¶ã ã¨ãåãèãæ¹ã¯ãScalaã§ãéç¨ããã¨æãã¾ãã
大ã¾ãã«ããããªæµãã§èãã¦ã¾ãã(ãªã¹ãã¯æåããä¸ãããããã¨ãããã§ããã)
ã(A)ãªã¹ããä½ãã
âã(B)åæããããæ¡ä»¶ã«åããã¦çµãè¾¼ãã
âã(C)åã
ã®è¦ç´ ãå å·¥ããã
âã(D)åã
ã®è¦ç´ ãå©ç¨ããæä½ãè¡ãã
Scalaã§ã¯ããªã¹ã(SetãMapãªã©ã®ã³ã¬ã¯ã·ã§ã³ãå«ã)ã«å¯¾ãã¦æ¡ä»¶ã«ããè¦ç´ ãæ½åºããã(filter)ãåã ã®è¦ç´ ãå å·¥ããçµæãæ°ãããªã¹ãã¨ãã¦çæããã(map)ãåã ã®è¦ç´ ã«æä½ãé©ç¨ããã(foreach)ãã¨ä¸è¨ã®æµãã®ããããã«åãããAPIãäºãç¨æããã¦ãã¾ãããã®APIãä¸è¨ã®æµãã«ã¯ãè¾¼ãã§ããã°å¦çãã§ãããããã¨è¨ãããã§ãã
ç°¡åãªä¾ã§èãã¦ã¿ã¾ããããããªãã¿ã®FizzBuzzåé¡ãã¡ãã£ã¨æ¹å¤ãã¦ã1ããNã¾ã§ã®æ´æ°ã®ä¸ã§ãå¶æ°ã®ãã®ã®ã¿FizzBuzzãããã¨ããåé¡ãã¨ãã¦ã¿ã¾ãã
å ã»ã©ã®æµãã«ãã¦ã¯ããã¨ã
ã(A)1ããNã¾ã§ã®Listãä½ãã
âã(B)å¶æ°ã®ãã®ã®ã¿æ½åºããã
âã(C)æåå(Fizz,Buzz,FizzBuzz)ã¾ãã¯ãã®ã¾ã¾ã«å å·¥ããã
âã(D)çµæãåºåããã
ãããªãã¾ãããããScalaã®ã³ã¼ãã§æ¸ãã¦ã¿ã¾ã
ã(A)(1 to N )ã
âã(B)filter{ n => n % 2 == 0 }ã
âã(C)map{ case n if n % 15 ==0 => "FizzBuzz";case n if % 3 == 0 => "Fizz";case n if n % 5 == 0 => "Buzz"; case n => n.toString } ã
âã(D) foreach{ e => pritnln(e)}ã
ãã¨ã¯ããããã¤ãªããã ãã§ãã
def fizzbuzz( n:Int ) = { 1 to n // (A)ãªã¹ããä½ã } filter{ n => n % 2 == 0 // (B)æ¡ä»¶ã«åããã¦çµãè¾¼ã } map { // (C)è¦ç´ ãå å·¥ãã case n if n % 15 == 0 => "FizzBuzz" case n if n % 3 == 0 => "Fizz" case n if n % 5 == 0 => "Buzz" case n => n.toString } foreach { e => println( e ) // (D) æä½ãè¡ã }
ãµã¤ãã®FizzBuzzã ã£ãããfilterãã¦ãã(B)ãåãé¤ãã°ããã ãã§ãã
ããã§ã¯ãåç´ãªæ´æ°ã®ãªã¹ããèãã¾ããããä¾ãã°æååã¯Charã®ãªã¹ãã§ãããMapã¯Tupple2(key,value)ã®ãªã¹ããXMLã¯scala.xml.Elemã®ãªã¹ããã¨æ§ã ãªãã®ããªã¹ãã¨ãã¦æãããã¨ãã§ãã¾ãã
ãããã¯ãªã¹ãã ã£!ãã¨æã£ãããä¸è¨ã®èãæ¹ãåºæ¥ãããã§ããã
ç·´ç¿åé¡ã¨ãã¦ãããã¹ããã¡ã¤ã«ãèªã¿è¾¼ãã§ãè¡çªå·ãä»ä¸ãã¦åºåããå¦çãèãã¦ã¿ã¾ãããã解çã¯ãGistã«è²¼ã£ã¦ããã¾ããè¦ãåã«ãã¿ãªãããèãã¦ã¿ã¦ãã ããã
ãå¤ãããªããä¸ç - immutableãªããã°ã©ãã³ã°
finalãªå¤æ°ãä¸å¤(immutable)ãªãã¸ã§ã¯ããå©ç¨ãããã¨ã§ãå¯ä½ç¨ãæããå ç¢ãªããã°ã©ã ã«ãªããã¨è¨ããã¦ãã¾ããããã§ã¯ãã®å¹æã«ã¤ãã¦è©³ããè¿°ã¹ããã¨ã¯æ§ãããã¦ãããã¾ãããä¸è¬çã«ããç¿æ £ã§ããã®ã¯ã¾ã¡ãããªãã§ãããã
valã®å©ç¨ã¯äºåæ¡ä»¶ãä¿è¨¼ãã(ãããããªã?)
Scalaã§ã¯ã"val"ã§å®£è¨ããå¤æ°ã¯åä»£å ¥ã§ãã¾ãããããã ããèãã¨ä½¿ãåæãããããã ãã¨æãããããããã¾ããã
ããå¤æ°ãå©ç¨ããæã«"å¤æ´ããã¦ããªã"ãã¨ãä¿è¨¼ããã¦ããã¨ããã®ã¯ãã¨ã¦ã¤ããªãå®å¿æãããã¾ãã(ç¹ã«ãã«ãã¹ã¬ãããå©ç¨ããããããç¨åº¦å¤§ããªã¢ããªã±ã¼ã·ã§ã³ã§ã¯)
ããã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹å¤æ°ã"var"(å¤æ´å¯è½)ãªå ´åããã®"var"ãå©ç¨ããå¦çã¯ãç¶æ ã«ä¾åãã¦ãã¾ããã¨ã«ãªãã¾ãã
URLã表ãã¯ã©ã¹ãä¾ã¨ãã¦èãã¾ãããã®URLã¯ã©ã¹ã¯ãã³ã³ã¹ãã©ã¯ã¿ã«æååã§URLãããããschemeãhoståãªã©ãè¿ãé¢æ°ããã¡ã¾ãã
class URL(var url:String ) { if( url == null )throw new IllegalArgumentException def scheme = url.split(":").first def hostname = url.split("/").toList.tail.dropWhile("" == ).first def pathinfo = url.split("/").toList.tail.dropWhile("" == ).tail }
ãã®URLãªãã¸ã§ã¯ãã®ããããã£urlããã©ããã®ã¿ã¤ãã³ã°ã§nullã代å
¥ããã¦ãã¾ã£ãããhostnameé¢æ°ãªã©ãå¼ã³åºãã¨NullPointerExceptionãthrowããã¦ãã¾ãã§ãããã
ãããé²å¾¡ããã«ã¯ãurlããããã£ãå©ç¨ããå¦çã§äºåã«nullãã§ãã¯ãè¡ãããããã¾ããã
ãããããurlãnullã®å ´åã«ãã®URLãªãã¸ã§ã¯ãã¯ã©ã®ããã«æ¯ãèãã®ãæ£ããä»æ§ã§ãããã? ä¾å¤? ããã¨ãnullãè¿ã?
ãã®urlããããã£ãå¤æ´ä¸å¯ã§ããã°ãä¸è¨ã®ãããªåé¡ã«ç
©ãããããã¨ã¯ããã¾ããã
urlããããã£ã¯ãnullã§ã¯ãªããã¨ãä¿è¨¼ããã¦ããããã§ãã
URLã¯ã©ã¹ã®å®£è¨ã§ã"var"ã«ãªã£ã¦ããç®æã"val"ã«å¤æ´ããã°ãå¿ã®å¹³å®ãå¾ããã¨ãã§ãã¾ãã
immutableãªã¯ã©ã¹ - caseã¯ã©ã¹ã®å©ç¨
å ã»ã©ã®URLã¯ã©ã¹ã®ãããªimutableãªã¯ã©ã¹ãä½ãæã£åãæ©ãæ¹æ³ãScalaã«ã¯ããã¾ãã
caseã¯ã©ã¹ã«ããã°ããã®ã§ãã
classãã¼ã¯ã¼ãã®åã«"case"ãã¤ãã¦ãã³ã³ã¹ãã©ã¯ã¿å¼æ°ã®var/valãå¤ããã ãã§ãã
case class URL( url:String ) { if( url == null )throw new IllegalArgumentException def scheme = url.split(":").first def hostname = url.split("/").toList.tail.dropWhile("" == ).first def pathinfo = url.split("/").toList.tail.dropWhile("" == ).tail }
ããã ãã§ããã®URLã¯ã©ã¹ã¯imutableãªã¯ã©ã¹ã«ãªãã¾ããä»ã«ãæ§ã ãªæ©æµãå¾ããã¨ãã§ãã¾ãã
- newãã¼ã¯ã¼ããªãã§URL("http://d.hatena.ne.jp/yuroyoro")ã®ããã«ãªãã¸ã§ã¯ããçæã§ãã
- å¼æ°ã®ããããã£ãèªåçã«èªã¿åãå°ç¨ã§å ¬éããã
- equals,hashCode,toStringãé©åã«å®è£ ããã
- ãã¿ã¼ã³ããã(å¾è¿°)ã§ä½¿ããããã«ãªã
// newãªãã§ã¤ã³ã¹ã¿ã³ã¹çæ scala> val url = URL("http://d.hatena.ne.jp/yuroyoro/" ) url: URL = URL(http://d.hatena.ne.jp/yuroyoro/) // ããããã£ã«ä»£å ¥ã§ããªã scala> url.url = null <console>:21: error: reassignment to val url.url = null ^ // èªã¿åãã§ãã scala> url.url res22: String = http://d.hatena.ne.jp/yuroyoro/ // åãããããã£ãæã¤ã¤ã³ã¹ã¿ã³ã¹å士ã¯"åå¤" // (equals,hashCodeãé©åã«å®è£ ããã¦ãã) scala> url == URL("http://d.hatena.ne.jp/yuroyoro/" ) res23: Boolean = true // toStringãèªç¶ã« scala> url.toString res24: String = URL(http://d.hatena.ne.jp/yuroyoro/)
Scalaã§ã¯ã©ã¹ãä½ãã¨ãã¯ã¾ããcaseã¯ã©ã¹ã§åé¡ãªããèããã¨ããããå§ã¾ããã¨ãã£ã¦ãéè¨ã§ã¯ããã¾ããã
å帰ã¨immutable
Scalaã®Listã¯ã©ã¹ã¯ãåºæ¬ã¯immutableã§ããã¤ã¾ããå¾ããè¦ç´ ã追å ãããåé¤ãããã§ãã¾ããã(mutableãªã³ã¬ã¯ã·ã§ã³ã使ãããå ´åã¯ãscala.collection.mutableããã±ã¼ã¸ã®ã¯ã©ã¹ã使ãã¾ãã
ãã¨ããListã«è¦ç´ 追å ã§ããªããªãã¦ä¸ä¾¿ããããã¨æãããããã¾ããã
ãã¨ãã°ãããæååä¸ã«åºç¾ããæåã®åæ°ãMap(æå -> åæ°)ã¨ããå½¢ã§æ°ããé¢æ°ãèãã¦ã¿ã¾ãã
javaã§ã¯ãããªæãã§ããããæåã«Mapãç¨æãã¦ãæåãåºç¾ãããã³ã«Mapã®å¤ãã¤ã³ã¯ãªã¡ã³ããã¦ããå½¢ã§ãã
static Map<Character,Integer> countChar( String s ){ Map<Character,Integer> m = new HashMap<Character,Integer>(); for ( char c :s.toCharArray() ){ if( m.containsKey(c)){ int cnt = m.get(c); m.put( c, cnt + 1); } else{ m.put(c, 1 ); } } return m; }
åæ§ã®å¦çãScalaã§æ¸ãã¦ã¿ã¾ãããã
def countChar( s:String ) = { val m = Map.empty[Char,Int] s foreach { c => val cnt = m.getOrElse(c,0) // ããã§mã«è¦ç´ ã追å ããããmã¯immutable m + ( c -> cnt + 1 ) } m }
Scalaã®Mapã¯immutableãªã®ã§ããã®ã¢ããã¼ãã¯ä½¿ãã¾ãããã§ã¯ã©ãããã®ã§ãããã?
æ段ã¯äºã¤ããã¾ãã
ä¸ã¤ã¯ãå©ç¨ããMapãmutableãªMapã«å¤æ´ãããã¨ã§ãã
ããä¸ã¤ã¯ãå帰ãå©ç¨ãã¦æ¸ãç´ãæ¹æ³ã§ãã
å帰ã§æ¸ãç´ãã¨ããããªæãã§ãã
def countChar( s:String ) = { // å帰ãããã¯ã¼ã«ã¼é¢æ° // å¼æ°lã®Charãªã¹ãã®å é è¦ç´ ã®åºç¾æ°ã+1ããMapãè¿ã def count( l:List[Char], m:Map[Char,Int] ):Map[Char,Int] = { if( l.isEmpty ){ // lã空Listã ã£ããå帰çµäº m }else { val cnt = m.getOrElse( l.head, 0 ) + 1 // lã®æ®ãã¨å é è¦ç´ ã®åºç¾æ°ã+1ããMapãå帰ã§æ¸¡ã count( l.tail, m + ( l.head -> cnt ) ) } } // ã¯ã¼ã«ã¼é¢æ°ã空Mapãä½ã£ã¦å¼ã³åºã count( s.toList, Map.empty[Char,Int] ) }
ããã§ãimmutableãªMapã®ã¾ã¾ã§ç®çã®å¦çãã§ãã¾ãããå帰ã®ããã«ã¯ã¼ã«ã¼é¢æ°ãä½ãã®ã¯ãããããã¿ã¼ã³ã§ãã
ã¡ãªã¿ã«ããã®éè¨å¦çã¯foldLeftãå©ç¨ãã¦ä¸è¡ã§æ¸ããããã¾ãããã®æã®ã³ã¬ã¯ã·ã§ã³ã®éè¨ç³»ã®å¦çã§foltLeftã使ãã®ã常å¥æ段ã§ãã
def countChar( s:String ) = (Map.empty[Char,Int] /: s ){( m ,c ) => m + ( c -> (m.getOrElse( c, 0 ) + 1)) }
ãªã«ããªãã§ãimmutableãããã®?
ããã§ã¯ããã¾ãããimmutableãªããã°ã©ãã³ã°ã¯ãä¸è¬çã«ã¯ç°¡æ½ãªè¨è¿°ã«ãªããã¨ãå¤ãã§ãããvarãå©ç¨ããæ¹ãããããããã³ã¼ãã«ãªããã¨ãããã§ãããã
ã¾ããimmutableãªããã°ã©ãã³ã°ã§ã¯ããã©ã¼ãã³ã¹é¢ã§ä¸å©ã«ãªããã¨ããããã¾ãã
ãã®ãããªå ´åã¯ãããªãã«varãå©ç¨ããæ¹ãããã§ãããã
ä¾ãã°ãScalaã®Listã¯ã©ã¹ã¯å©ç¨è
ããããã¨immutableãªã¯ã©ã¹ã§ãããå
é¨ã®å®è£
ã¯varã使ã£ã¦æ§è½é¢ãèæ
®ãã¦ãã¾ãã
/scala/tags/R_2_7_5_final/src/library/scala/List.scala – Scala
ããã¿ã¼ã³é!使å¾ã§ã!ã - ifãããã¿ã¼ã³ããã
æ¡ä»¶å¤æãè¡ããªãããã°ã©ã ã¨ããã®ã¯ã¾ãã§ããããæ®éã¯ifæã§æ¡ä»¶åå²ãæ¸ãã¾ããã?
Scalaã§æ¡ä»¶åå²ãè¡ãã«ã¯ããã¡ããifæãå©ç¨ã§ãã¾ããããã¿ã¼ã³ããã(matchå¼)ãå©ç¨ããã¨æè»ãªè¨è¿°ãã§ããããã«ãªãã¾ãã
ã³ããæ¬ããã®å¼ç¨ã§ãããjavaã®switchã¨scalaã®matchå¼ã®è¨è¿°ã®æ¯è¼ã§ãã
Java:
switch( <ã»ã¬ã¯ã¿ã¼å¼> ){ case å ´å : å¦ç ... }
Scalaã®matchå¼:
<ã»ã¬ã¯ã¿ã¼å¼> match {
case ãã¿ã¼ã³ => å¦ç
...
}
ããã ãã§ãã¨å¯¾ãã¦éããç¡ãããã«è¦ãã¾ããããããScalaã§ã¯ãã¿ã¼ã³ã¨ãã¦è¨è¿°ã§ãã表ç¾ãJavaã«æ¯ã¹ã¦ã¯ããã«æè»ãªã®ã§ãã
ãããå¼ã®åºæ¬
Javaã§ã¯ãcaseã®å¾ã«æ¸ããã®ã¯æ´æ°å(Enumå«ã)ã¨æåå(char)ã ãã§ããã
Scalaã§ã¯ã以ä¸ã®ãããªãã¿ã¼ã³ãæ¸ããã¨ãã§ãã¾ãã
ã¯ã¤ã«ãã«ã¼ããã¿ã¼ã³ | case _ | ãããããã®ã«ããããããã¯default |
å®æ°ãã¿ã¼ã³ | case "foo" | "foo"ãªã©å¤ã«ãããã |
å¤æ°ãã¿ã¼ã³ | case n | å ¨ã¦ã«ããããããããããããçµæãnã¨ããå¤æ°åã§ä½¿ããã |
åä»ããã¿ã¼ã³ | case d:Double | Doubleåã®å ´åã«ããã |
ãã¿ã¼ã³ã¬ã¼ã | case n if n % 2 == 0 | ifã§æ¡ä»¶ãæå®ãä¾ã§ã¯å¶æ°ã®ã¿ããã |
ã³ã³ã¹ãã©ã¯ã¿ãã¿ã¼ã³ | case URL( u ) | caseã¯ã©ã¹ã§ããURLã¯ã©ã¹ã«ãããããURLã¯ã©ã¹ã®ããããã£urlãå¤æ°uã«æç¸ |
matchå¼ã§ä½ãããããã®?
matchå¼ã¯ãcaseã¯ã©ã¹ã¨çµã¿åããã¦ä½¿ãã¨å¹¸ã度ãã¤ãã¤ãã¨ã«ãªãã¾ãã
é»è©±çªå·ã®caseã¯ã©ã¹Telãå®ç¾©ãã¾ããå¸å¤å±çªãå¸å å±çªãå å ¥è çªå·ãããããã£ã§æã¤ã·ã³ãã«ãªãã®ã§ãã
case class Tel( area:String, local:String, sub:String)
æºå¸¯é»è©±çªå·(ããã§ã¯090ã®ãã®ã®ã¿ã¨ãã¾ã)ã¨ãã以å¤ã§å¦çãåãããå ´åãmatchå¼ã§ãããªã«ç°¡åã«æ¸ããã¨ãã§ãã¾ã
scala> val tel = Tel( "090","1234","5678") tel: Tel = Tel(090,1234,5678) scala> tel match { | case Tel("090", l, s ) => println("æºå¸¯:090-%s-%s".format( l, s ) ) | case Tel( a, l, s ) => println("é»è©±çªå·:%s-%s-%s".format( a, l, s ) ) | } æºå¸¯:090-1234-5678
ãcase Tel("090", l, s ) => ...ãã¯Telãªãã¸ã§ã¯ãã®areaããããã£ã"090"ã ã£ããããããã¦ãæ®ãã®localããããã£ãå¤æ°lã«ãsubããããã£ãå¤æ°sã«æç¸ããã¦ãã¾ãã
ãã®ããã«ãcaseã¯ã©ã¹ã«å¯¾ãã¦ã³ã³ã¹ãã©ã¯ã¿ãã¿ã¼ã³ã§matchããããã¨ã§ããã®caseã¯ã©ã¹ã®ãªãã¸ã§ã¯ããæã¤ããããã£ãããããããæã«å¤æ°ã«æç¸ãã¦å©ç¨ã§ããã®ã§ãã
æ£è¦è¡¨ç¾ããã¿ã¼ã³ãããã§ä½¿ãã¾ããURLãæ£è¦è¡¨ç¾ã§scheme,hostname,pathinfoã«åå²ããã®ã¯ãããªæãã§ãã(æ£è¦è¡¨ç¾èªä½ã¯é©å½ã§ãï¼ï¼)
scala> val url = "http://d.hatena.ne.jp/yuroyoro" url: java.lang.String = http://d.hatena.ne.jp/yuroyoro scala> val r = """(.+)://([^/]+)/?(.*)*""".r r: scala.util.matching.Regex = (.+)://([^/]+)/?(.*)* scala> url match { | case r( s, h, _ ) => println( "%sã®%s" format( s, h ) ) | case _ => println("URLãããªãã?") | } httpã®d.hatena.ne.jp
Scalaã§ã¯ãval r = """(.+)://([^/]+)/?(.*)*""".r ãã®ããã«æ£è¦è¡¨ç¾ã®æååã«.ré¢æ°ãå¼ã³åºããã¨ã§æ£è¦è¡¨ç¾ãªãã¸ã§ã¯ããåå¾ã§ãã¾ãããã®æ£è¦è¡¨ç¾ãªãã¸ã§ã¯ãã¯matchå¼ã§å©ç¨ã§ãã¦ãæ£è¦è¡¨ç¾å
ã®ãã¿ã¼ã³ãmatchå¼ã§å¤æ°ãã¿ã¼ã³ã¨ãã¦æç¸ãã¦å¾ããã¨ãã§ããã®ã§ãã
便å©ã§ãã?
ããããæ¡ä»¶åå²ã¯matchå¼ãifæã¯ä¸é
æ¼ç®åããããã®å¢ãã®ã»ããããããã§ãã
nullã ã£ã¦? ãããªãã®ã¯å¿ããã - Option
Optionåã£ã¦ããã®ã便å©ããã¦é¼»è¡ãã»ã¨ã°ããã¾ãã
scala.Option
ãMayBeã¢ããã£!ããªãã¦ããã¨åæ¹é¢ãããã«ããã³ã«ããã¦ãã¾ããããªã®ã§æ§ãã¾ãããOptionã£ã¦ã®ã¯å¤ãåå¨ãããããããªãç¶æ ããããããã®ã§ãã
Optionã¯caseã¯ã©ã¹ã§ããOptionåã«ã¯ããµãã¿ã¤ãã¨ãã¦å¤ãåå¨ããå ´åã®Someã¨ãå¤ããªãå ´åã®Noneãããã¾ãã
è«ããã½ã¼ã¹ã§ããjavaã®Map#getã¯ãå¤ãåå¨ããªãå ´åã¯nullãè¿ãã¾ããã
Scalaã®Map#geté¢æ°ã¯ãå¼æ°ã®keyã«å¯¾ãã¦å¤ãOptionåã§"å
ãã§"ãããã¾ããå¤ãããå ´åã¯Some(å¤)ã§ããªãå ´åã¯Noneãè¿ãã¾ãã
scala> val m = Map('a' -> 1 , 'b' -> 2 ) m: scala.collection.immutable.Map[Char,Int] = Map(a -> 1, b -> 2) scala> m.get('z') res97: Option[Int] = None â å¤ããªãã®ã§None scala> m.get('a') res96: Option[Int] = Some(1) â å¤ãããã®ã§Some(1) scala> m.get('a').get â Someããå¤ãåãåºãã®ã¯Option#get res99: Int = 1
ãªãã§ããããOptionã«"å
ã"ã®ã§ãããã?åãåºãã®ãé¢åãããªãã§ãã?
ããã§ã¯ãªãã®ã§ããOptionã¯caseã¯ã©ã¹ã§ãã®ã§ãmatchå¼ã使ãã¾ããmatchå¼ã¨çµã¿åãããã¨ãå¤ãããå ´åã®å¦çã¨ãªãå ´åã®å¦çãèªç¶ã¨åé¢ã§ãã¾ãã
scala> m.get('b') match { | case Some( n ) => println(n) | case None => println("none.") | } 2
å¤ãããå ´åã®ã¿å¦çãè¡ãããå ´åã¯ãmatchå¼ããå¿
è¦ããã¾ãããOption#foreachã§Someã®å ´åã®ã¿å¦çãè¡ããããã¨ãã§ãã¾ããnullãã§ãã¯ãªãã¦ä¸è¦ã§ã!
scala> m.get('a').foreach{ n => println( "find! %s" format( n ) )} find! 1
Scala Libraryã®APIã§ã¯nullãè¿ããã®ã¯åå¨ãã¾ãããå¤ããªãããããããªãAPIã¯ãã¹ã¦Optionåãè¿ãããããã«ãªã£ã¦ããã®ã§ãã
Scalaã§nullãã§ãã¯ãå¿ è¦ãªå±é¢ã¯ãJavaã®ã©ã¤ãã©ãªãå©ç¨ããå ´åã§ãããããã®å ´åããnullã ã£ããNoneãè¿ãããã«ã©ãããã¦ãããã®ã便å©ã ã¨æãã¾ãã
é¢æ°ã"ãã®ãã¤ãã"ãã - é¢æ°ãªãã¸ã§ã¯ã
ãªã¹ãã®ã¨ããã§èª¬æããèãæ¹ã§ããããªã段éã«ããã¦ããã®ã§ãããããä¸ã¤ã®ã«ã¼ãã®ä¸ã§ãçµãè¾¼ã¿ãå å·¥ãæä½ãä¸åº¦ã«ãã£ã¦ããããããªãããã¨æãããæ¹ãå¤ãã¨æãã¾ãã
ããã»ã©ã®FizzBuzzåé¡ãæ¡ä»¶ãå¶æ°ã§ã¯ãªãå¥æ°ã«ããããå¼ã³åºãå´ãæ¡ä»¶ãæå®ã§ããããã«ãããå ´åã¯ã©ã®ãããªã¢ããã¼ããã¨ãã¾ãã?
Javaã®å ´åã§ãã¨ãå¶æ°ãå¥æ°ããå¤å®ããå¦çãã¡ã½ããã¨ãã¦æ½åºãããã¨ããã¢ããã¼ããããã¾ãããããã¯ç¹å®ã®interfaceãå®è£ ãããªãã¸ã§ã¯ãã«æ¡ä»¶å¤æãå§è²ããããªã©ã§ãããã?
Scalaã§ã¯ããã£ã¨ã¹ãã¬ã¼ããªã¢ããã¼ããã¨ãã¾ããæ¡ä»¶ãå¤æãã"é¢æ°ãªãã¸ã§ã¯ã"ãå¼æ°ã«ãããããã«ããã®ã§ãã
def fizzbuzz( n:Int, cond:Int => Boolean ) = { 1 to n // (A)ãªã¹ããä½ã } filter{ cond // (B)æ¡ä»¶ãå¼æ°ã®é¢æ°ãªãã¸ã§ã¯ãã§çµã } map { // (C)è¦ç´ ãå å·¥ãã case n if n % 15 == 0 => "FizzBuzz" case n if n % 3 == 0 => "Fizz" case n if n % 5 == 0 => "Buzz" case n => n.toString } foreach { e => println( e ) // (D) æä½ãè¡ã }
ãããæ¹è¯çã®fizzbuzzé¢æ°ã§ããå¼æ°ã«ã"Intåãå¼æ°ã§åãåã£ã¦Booleanãè¿ãé¢æ°"ã追å ãã¾ããã(B)ã®æ¡ä»¶ã®çµãè¾¼ã¿ã¯ããã®å¼æ°ã§ããã£ãé¢æ°ãªãã¸ã§ã¯ãã«ãããã¦ãã¾ãã
ããã§ããã®fizzbuzzé¢æ°ã®å©ç¨è ã¯çµãè¾¼ã¿ã®æ¡ä»¶ã好ãã«æå®ã§ããããã«ãªãã¾ãããå¥æ°ã ãããã3ã®åæ°ã ããããªãã ããã対å¿ã§ãã¾ãã
scala> fizzbuzz( 30 , (n:Int) => n % 2 == 1 ) 1 Fizz Buzz 7 ...
ã¤ãªãã¦ããã - ããããã¦:UNIX
æåã«èª¬æãã¾ããããªã¹ããå¦çãããã¨ãã«ãããªã¹ããä½ã£ã¦ãæ¡ä»¶ãçµã£ã¦ãå å·¥ãã¦â¦ãã¨ããããã«ãã¡ãããªå¦çãã¤ãªãã¦ããã¾ããã
ãã®èãæ¹ãã©ããã§èãããã¨ããã¾ããã?
ãUNIXã¨ããèãæ¹âãã®è¨è¨ææ³ã¨å²å¦ ãã¨è¨ãæ¬ã«ããã¾ãããUNIXã®ææ³ã®ä¸ã¤ã«ã"å°ããæ©è½ã®ã³ãã³ããããã¤ãã§ã¤ãªãã§è¤éãªå¦çããã"ã¨ãããã®ãããã¾ãã
ããã»ã©ã®èãæ¹ã¨ä¼¼ã¦ãã¾ãã? 俺ãScalaã§ããã°ã©ã ãæ¸ãã¨ãã«ã¯ããã®"ã¤ãªãã¦ããã"ã¨ããã®ãæèãã¦ãã¾ãã
ä½ãå ¥åãåãåã£ã¦çµæãè¿ãé¢æ°ãåºæ¥ãã ãã¡ãããåä½ã§ããããç¨æãã¦ããã°ããã¨ãã¨ä½¿ãåããå¹ãã¾ããéä¸ã«å¦çãæãã ããå·®ãæ¿ãããâ¦ã
ãªã®ã§ãé¢æ°ãä½ãã¨ãã¯ãã§ããã ãã¡ããããããã¦çµæãListãMapãOptionãªã©"ããããå½¢"ã§è¿ãããã«ãã¦ããã®ãå¿ããã¦ãã¾ããListãOptionãªããã¤ãªãã§ããéä¸ã§çµæã空ã®ListãNoneã«ãªã£ã¦ãã¾ã£ãå ´åã¯ä»¥éã®å¦çã¯åç´ã«ã¹ãããããã¾ããã
çµæãè¿ããªãUnitåã®é¢æ°ã¯ããã®"ã¤ãªã"ã®çµç«¯ã«ããæ¥ç¶ã§ããªãã®ã§ã使ãåæããã¾ãããããã¾ãããUnitåãã§ããã ãå°ããªåä½ã«ãããã¨ããã¾ãæèãã¦ãã¾ãã
ãããããã¾ããã"ã¤ãªãã¦ããã"ã¯ã¨ã£ã¦ã大äºãªãã¨ã ã¨æãã¾ãã