관리 메뉴

nkdk의 세상

scala 관련 펑션 모음 #1 전체적 펑션에는 뭐가 있을까요? 본문

My Programing/Scala&Lift

scala 관련 펑션 모음 #1 전체적 펑션에는 뭐가 있을까요?

nkdk 2010. 9. 17. 11:05
안녕하세요? 이번에는 스칼라 관련 펑션들을 쭈욱 나열해 봤습니다.

직접 제가 실행해서 전부 된 내용이니까요. 한번쯤 쭉 돌려 보시면 이해가 되실 듯 합니다.

자 시작 ----

scala> import java.util._
import java.util._

scala> val d = new Date
d: java.util.Date = Tue Sep 14 15:35:47 JST 2010

scala> val te = "sss"
te: java.lang.String = sss

scala> val teleng = te.length
teleng: Int = 3

scala> println("hello")
hello

--for--
scala> for {i <- 1 to 3}
      print(i)         
123

scala> for {i <- 4 to 5                               
      j <- 90 to 91
      k <- 120 to 122}
      println(i + " " + j + " " + k) 

----scala----
scala> import scala.io._
import scala.io._

scala> def toInt(in: String): Option[Int] =  
      try {
      Some(Integer.parseInt(in.trim))
      } catch {
      case e: NumberFormatException => None
      }
toInt: (in: String)Option[Int]

----Sum.Scala----
import scala.io._

def toInt(in: String): Option[Int] =
  try {
    Some(Integer.parseInt(in.trim))
  } catch {
    case e: NumberFormatException => None
  }

def sum(in: Seq[String]) = {
  val ints = in.flatMap(s => toInt(s))
  ints.foldLeft(0)((a, b) => a + b)
}

print("enter some number and press ctrl-d")
val input = Source.fromInputStream(System.in)

// 2.7 (collect) -> 2.8 changed ().toSeq
val lines = input.getLines().toSeq

println("Sum "+ sum(lines))

-.-basic scala syntax-.-
Integer: 1882, -1
Boolean: true, falseDouble: 1.0d, 1d, 1e3
Long: 42L
Characters: 'b', '2', '?'
Strings: "hello, good"

--multi line--
scala> """Hello
     | multi Line
     | """
res2: java.lang.String = 
Hello
multi Line

--xml syntax--
scala> val xmlxml = <b>Foo</b><ul>{(1 to 4).map(aa => <li>{aa}</li>)}</ul>
xmlxml: scala.xml.NodeBuffer = ArrayBuffer(<b>Foo</b>, <ul><li>1</li><li>2</li><li>3</li><li>4</li></ul>)


--callback and nonameMethod--
object Timer
{
  def oncePerSecond(callback: () => Unit): Unit =
  {
    while (true)
    {
      callback()
      Thread.sleep(1000)
    }
  }

  def timeFlies(): Unit = 
  { Console.println("Time flies when you're having fun(ctionally)..."); }

  def main(args: Array[String]): Unit =
  {
    oncePerSecond(timeFlies)
  }
}

====> 
object Timer
{
  def oncePerSecond(callback: () => Unit): Unit =
  {
    while (true)
    {
      callback()
      Thread.sleep(1000)
    }
  }

  def main(args: Array[String]): Unit =
  {
    oncePerSecond(() => 
      Console.println("Time flies... oh, you get the idea."))
  }
}

===>
object Timer
{
  def periodicCall(seconds: Int, callback: () => Unit): Unit =
  {
    while (true)
    {
      callback()
      Thread.sleep(seconds * 1000)
    }
  }

  def main(args: Array[String]): Unit =
  {
    periodicCall(1, () => 
      Console.println("Time flies... oh, you get the idea."))
  }
}

--define variable--
val msg:String = "Hello, World"
msg = "Good Bye"  <-error   val is do not change.

var greeting = "Hello, World"
greeting = "Good Byte" <-not error var is possible change.

-- if --
def max(x: Int, y: Int): Int = {
   if ( x > y ) x
   else y
}

-- class define and override --
class Rational(val n:Int, val d:Int) {

   override def toString() = {
       n + "/" + d
   }

}

scala> val half=new Rational(11, 22)
half: Rational = 11/22

scala> half.n
res2: Int = 11


--def function--
scala> def curriedSum(x: Int)(y: Int) = x + y
curriedSum: (x: Int)(y: Int)Int

scala> curriedSum(109)(19)
res7: Int = 128

-- recurrence --
scala> def sum(f: Int => Int) (start: Int, end: Int) : Int = {
        if ( start > end )
           0
        else
           f(start) + sum(f) (start + 1, end)
     }
sum: (f: (Int) => Int)(start: Int,end: Int)Int

scala> sum( x=> x*x)(1,10)
res12: Int = 385

-- sum() is referentially transparent --
scala> sum(x => x)(1, 8) 
res18: Int = 36

-- simply function --
scala> def plus(x: Int, y: Int) = {
         x + y
      }
plus: (x: Int,y: Int)Int

scala> plus(3,5)
res19: Int = 8



class Reference[a] {

     private var contents: a = _

     def set(value: a) { contents = value }

     def get: a = contents

}

-- simply interface --
    
scala> object Moose {
     | def bark = "wooff"
     | }
defined module Moose

scala> import Moose._
import Moose._

scala> bark
res49: java.lang.String = wooff

-- list define --
scala> val v=("ssss", 1122, 1.5) 
v: (java.lang.String, Int, Double) = (ssss,1122,1.5)

scala> List(v)
res55: List[(java.lang.String, Int, Double)] = List((ssss,1122,1.5))

-- Method Declaration --
1))
scala> def foo(a: Int): String = a.toString
foo: (a: Int)String

scala> foo(1000)
res60: String = 1000

2))
scala> def f2(a: Int, b: Boolean) = if (b) a.toString else "false"
f2: (a: Int,b: Boolean)java.lang.String

scala> f2(10, true)
res63: java.lang.String = 10

scala> f2(10, false)
res64: java.lang.String = false

3)) list of T
scala> def list[T](p: T): List[T] = p:: Nil
list: [T](p: T)List[T]

scala> list("11", "sss", 111)              
res69: List[(java.lang.String, java.lang.String, Int)] = List((11,sss,111))

4)) reduceLeft -->> many num -> largest 
scala> def largest(as: Int*): Int = as.reduceLeft((a, b) => a max b)
largest: (as: Int*)Int

scala> largest(2,4,5)
res70: Int = 5

5)) foldLeft -->> many String -> plus all String
scala> def mkString[T](as: T*): String = as.foldLeft("")(_ + _.toString)
mkString: [T](as: T*)String

scala> mkString("sss", "jsdj", "three", "s")                            
res75: String = sssjsdjthrees

6)) abstract
scala> abstract class Base { 
     | def thing: String
     | }
defined class Base

scala> class One extends Base {   
     | def thing = "moof"      
     | }
defined class One

scala> class Two extends One {
     | override val thing = (new java.util.Date).toString
     | }
defined class Two

scala> class Three extends One {
     | override lazy val thing = super.thing + (new java.util.Date).toString
     | }
defined class Three

scala> (new Three).thing
res7: java.lang.String = moofWed Sep 15 10:37:29 JST 2010


-- Variable Declaration --
1)) basic variable declaration
// var = modify ok, val = modify no
scala> var y: String = "Moff"
y: String = Moff
scala> val x: String = "moffX"
x: String = moffX

2) pair variable Declaration ( pair )
scala> val (i1: Int, s1: String) = Pair(33, "Mooff")
i1: Int = 33
s1: String = Mooff


-- code blocks --
scala> def meth4(): String = {
     | val d = new java.util.Date()
     | d.toString()
     | }
meth4: ()String

scala> meth4
res12: String = Wed Sep 15 10:54:22 JST 2010

-- call by name --
// diffed --> delayed(t: => long) and noDelayed(t: long)
1) delayed ( class reference )
scala> def delayed(t: => Long) = {
     | println("Indeleay")        
     | println("param: "+ t)      
     | t                    
     | }
delayed: (t: => Long)Long

scala> delayed(nano())
Indeleay
getting nano
param: 1284516216253827000
getting nano
res18: Long = 1284516216254443000

2) nodelayed ( var declaration )
scala> def nodeleayed(t: Long) = {
     | println("no delay")
     | println("param: "+ t)
     | t
     | }
nodeleayed: (t: Long)Long

scala> nodeleayed(nano())
getting nano
no delay
param: 1284516400999580000
res20: Long = 1284516400999580000

-- Method Invocation --
1) function method apply
scala> class Ap{
     | def apply(in: Int) = in.toString
     | }
defined class Ap

scala> val a = new Ap
a: Ap = Ap@7bb28246

scala> a(44)
res30: java.lang.String = 44

2) function method update
scala> class Up {
     | def update(k: Int, v: String) = println("Change: "+ k + " " + v)
     | }
defined class Up

scala> val u = new Up
u: Up = Up@63df0310

scala> u(44) = "yeah man"
Change: 44 yeah man

3) function overload
scala> class Update {
     | def update(what: String) = println("Singler: "+ what)
     | def update(a: Int, b: Int, what: String) = println("2d update")
     | }
defined class Update

scala> val u = new Update
u: Update = Update@ee01430

scala> u() = "Food"
Singler: Food

scala> u(3,40) = "ss"
2d update

-- Case Classes -- like struture?
1)) class define
scala> case class Stuff(name: String, age: Int)
defined class Stuff

scala> val s = Stuff("dada", 40)
s: Stuff = Stuff(dada,40)

scala> s.toString
res48: String = Stuff(dada,40)

2)) Variable diff
scala> s == Stuff("dada", 40)
res49: Boolean = true

scala> s == Stuff("dada", 41)
res50: Boolean = false

scala> s.name
res51: String = dada

scala> s.age
res52: Int = 40

3)) class and object declare
scala> class Stuff(val name: String, val age: Int) {            
     | override def toString = "Stuff("+name+","+age+")"        
     | override def hashCode = name.hashCode + age              
     | }
defined class Stuff

scala> object Stuff {                                         
     | def apply(name: String, age: Int) = new Stuff(name, age)
     | def unapply(s: Stuff) = Some((s.name, s.age))           
     | }                                                       
defined module Stuff

scala> val s = Stuff("nam", 100)
s: Stuff = Stuff(nam,100)

scala> s
res63: Stuff = Stuff(nam,100)

scala> s.age
res64: Int = 100

scala> s.name
res65: String = nam

-- Basic Pattern Matching --
1) basic
scala> 44 match {
     | case 44 => true
     | case _ => false
     | }
res66: Boolean = true

2) class match
scala> Stuff("David", 40) match {
     | case Stuff("David", 40) => true
     | case _ => false
     | }
res67: Boolean = true

3) any age class match
scala> Stuff("David", 40) match {     
     | case Stuff("David", _) => true 
     | case _ => false               
     | }
res68: Boolean = true

4) instance pattern matching
val x = "abc" // String

x match {
  case d: java.util.Date => "The Date is "+ d.getTime
  case u: java.net.URL => "The URL" + u.getPath
  case s: String => "String: " + s
  case _ => "some else"
}

previous code java
if (x instanceOf Date) return "The Date is "+ ((Date) x).getTime();
....


-- if/else and while --
1) basic if
scala> val exp = true
exp: Boolean = true

scala> if (exp) println("aaa")
aaa

2) basic if/else
scala> val i: Int = if (exp) { 19999 
     | } else {
     | val j = System.currentTimeMillis
     | (j%100L).toInt
     | }
i: Int = 19999

3) while
while(exp) {
println("gogogo")
}

-- for comprehension --
1)) basic for
scala> for { i <- 1 to 3} println(i)
1
2
3

2)) use 2 for
scala> for {i <- 1 to 3  
     | j <- 1 to 3} print(i + " " + j)
1 11 21 32 12 22 33 13 23 3
scala> for {i <- 1 to 3               
     | j <- 4 to 6} print(i +"and" + j + " ")
1and4 1and5 1and6 2and4 2and5 2and6 3and4 3and5 3and6 

3)) for use if
scala> def isOdd(in: Int) = in %2 == 1         
isOdd: (in: Int)Boolean

scala> for {i <- 1 to 5 if isOdd(i)} println(i)
1
3
5

scala> for {i <- 1 to 5 if (i % 2 == 1)} println(i)
1
3
5

scala> val lst = (1 to 18 by 3).toList
lst: List[Int] = List(1, 4, 7, 10, 13, 16)

scala> for {i <- lst; j<-lst if isOdd(i * j)} yield i * j
res110: List[Int] = List(1, 7, 13, 7, 49, 91, 13, 91, 169)

for (i <- 15 from 10) yield i

scala> for (i <- 10 to 15) yield i  
res113: scala.collection.immutable.IndexedSeq[Int] = Vector(10, 11, 12, 13, 14, 15)

-- throw, try/catch/finally, and synchronized --
1)) normal exception
scala> throw new Exception("sososo")
java.lang.Exception: sososo
at .<init>(<console>:13)
at .<clinit>(<console>)

2)) exception and finally 
scala> try {                      
     | throw new Exception("svsv")
     | } finally {                
     | println("gogogo")          
     | }                          
gogogo
java.lang.Exception: svsv
at .liftedTree1$1(<console>:7)
at .<init>(<console>:6)
at .<clinit>(<console>)
at RequestResult$.<init>(<console>:9)
...

3)) try/catch
scala> try {Integer.parseInt("dododo")} catch 
     | { case _ => 0 }
res8: Int = 0

4)) synchronized
scala> def foo(): Int = synchronized {
     | 66
     | }
foo: ()Int

scala> foo
res11: Int = 66

-- comments --
/*
This is a multi line comment
*/
/* 
good
  /*
    good2
  */
goodend
*/
// one line comment

-- scala, ruby, java diff --
scala> def with42(in: Int => Int) = in(42)
with42: (in: (Int) => Int)Int

scala> with42(33 +)
res22: Int = 75

-- Scala List, Tuple, Option, and Map classes --
1)) List, Array, Map
scala> val x = List(1,2,3,4)
x: List[Int] = List(1, 2, 3, 4)

scala> x.filter(a => a % 2 == 0)
res23: List[Int] = List(2, 4)
 - Array
scala> val a = Array(1,2,3)
a: Array[Int] = Array(1, 2, 3)

scala> a(1)
res40: Int = 2

 - Map
scala> val m= Map("one" -> 1, "two" -> 2, "three" -> 3)
m: scala.collection.immutable.Map[java.lang.String,Int] = Map((one,1), (two,2), (three,3))

scala> m("one")
res41: Int = 1

 - to and by
scala> 0 to 20 by 2
res42: scala.collection.immutable.Range = Range(0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
 
 - take
scala> (1 to Integer.MAX_VALUE - 1).take(6)  
res48: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6)

2)) List[T] linked list of type
scala> val ff = 1 :: 2 :: "3" :: Nil
ff: List[Any] = List(1, 2, 3)

scala> val inttest = new ::(1, new ::(2, new :: (3, Nil)))
inttest: scala.collection.immutable.::[Int] = List(1, 2, 3)

scala> inttest
res50: scala.collection.immutable.::[Int] = List(1, 2, 3)

scala> val intlist = List[Int](1,5,2)
intlist: List[Int] = List(1, 5, 2)

 -merge num + val
scala> 22 :: intlist
res51: List[Int] = List(22, 1, 5, 2)

 -merge val + val
scala> val xx = List(1,2,3)
xx: List[Int] = List(1, 2, 3)

scala> val yy = List(90,91,92)
yy: List[Int] = List(90, 91, 92)

scala> xx ::: yy
res52: List[Int] = List(1, 2, 3, 90, 91, 92)

3)) Getting Functional ( filter, remove )
scala> List(1,2,3).filter(x=> x % 2 == 1)
res53: List[Int] = List(1, 3)

scala> List(1,2,3).remove(x => x % 2 == 1)
res55: List[Int] = List(2)
-->
scala> def isOdd(x: Int) = x % 2 == 1
isOdd: (x: Int)Boolean
scala> List(1,2,3).filter(isOdd)     
res57: List[Int] = List(1, 3)

 -- isDigit
"99 Red Balloons".toList.filter(Character.isDigit)
res59: List[Char] = List(9, 9)

 === Character.isDigit etc ===
 isInstanceOf               isDefined                  isDigit
isHighSurrogate            isISOControl               isIdentifierIgnorable
isJavaIdentifierPart       isJavaIdentifierStart      isJavaLetter
isJavaLetterOrDigit        isLetter                   isLetterOrDigit
isLowSurrogate             isLowerCase                isMirrored
isSpace                    isSpaceChar                isSupplementaryCodePoint
isSurrogatePair            isTitleCase                isUnicodeIdentifierPart
isUnicodeIdentifierStart   isUpperCase                isValidCodePoint
isWhitespace
===             ===        ===

 -- takeWhile --
scala> "Elwood eats mice".takeWhile(c => c != 'a')
res65: String = Elwood e

 -- toLowerCase --
scala> List("A", "Cat").map(s => s.toLowerCase)
res0: List[java.lang.String] = List(a, cat)
 -->
scala> List("A", "Cat").map(_.toLowerCase)
res2: List[java.lang.String] = List(a, cat)
scala> List("A", "Cat").map(_.length)
res4: List[Int] = List(1, 3)

 4)) Functional Methods #2
scala> trait Person {def first: String }
defined trait Person

scala> val d = new Person { def first = "David" }
scala> val e = new Person { def first = "Jhon" }
scala> val a = new Person { def first = "Arcman" }

scala> List(a,d,e).map(_.first)                   
res9: List[String] = List(Arcman, David, Jhon)

List(a,d,e).map(n => <li>{n.first}</li>)
scala> List(a,d,e).map(n => <li>{n.first}</li>)
res10: List[scala.xml.Elem] = List(<li>Arcman</li>, <li>David</li>, <li>Jhon</li>)

 -- sort ( possible Int, String or etc)
scala> List(99, 2,1,45).sort(_ < _)
res12: List[Int] = List(1, 2, 45, 99)

 -- sort length
scala> List("bb", "a", "elwood", "archersss").sort(_.length > _.length)
res14: List[java.lang.String] = List(archersss, elwood, bb, a)

 -- list person valid --
scala> trait Person {
      def age: Int
      def first: String
      def valid: Boolean
      }
defined trait Person

scala> def validByAge(in: List[Person]) =
     | in.filter(_.valid).
     | sort(_.age < _.age).
     | map(_.first) 
 
scala> val p1 = new Person { def age = 12; def first = "ajajaj"; def valid = true}

scala> val p2 = new Person { def age = 22; def first = "bjbjbj"; def valid = true}

scala> val p3 = new Person { def age = 32; def first = "cjcjcj"; def valid = true}

scala> val listP = List(p1, p2, p3)                                               
listP:List[java.lang.Object with Person]=List($anon$1@4c56291a,$anon$1@3f29a75a,$anon$1@31d47845)

// sort age, filter valid, map first
scala> validByAge(listP)
res1: List[String] = List(ajajaj, bjbjbj, cjcjcj)

// max or min
scala> List(8,6,22,20).reduceLeft(_ max _)
res7: Int = 22
scala> List(8,6,22,20).reduceLeft(_ min _)
res8: Int = 6

// length diff
scala> List("Moose", "cow", "A", "da").reduceLeft((a, c) => if (a.length > c.length) a else c)
res36: java.lang.String = Moose

// foldLeft
scala> List(1,3,4).foldLeft(4)(_ - _) 
res45: Int = -4

scala> List("b", "a", "elwood", "archer").foldLeft(0)(_ + _.length)       
res48: Int = 14

// toList
scala> val n = (1 to 10 by 3).toList
n: List[Int] = List(1, 4, 7, 10)

// logical function ( d = 
scala> val nmapval = n.map(d => n.map(i => d*i))
nmapval: List[List[Int]] = 
List(List(1, 4, 7, 10), List(4, 16, 28, 40), List(7, 28, 49, 70), List(10, 40, 70, 100))

// isOdd, isEven, 1-10 filter and flatMap
scala> n.filter(isEven).flatMap(i => n.filter(isOdd).map(j => i * j))
res0: List[Int] = 
List(2, 6, 10, 14, 18, 4, 12, 20, 28, 36, 6, 18, 30, 42, 54, 8, 24...

scala> for {i <- n if isEven(i); j <- n if isOdd(j)} yield i * j
res1: List[Int] = 
List(2, 6, 10, 14, 18, 4, 12, 20, 28, 36, 6, 18, 30, 42, 54, 8, 24, 40, 56, 72, 10, 30, 50, 70, 90)

4)) tuples  (( Pair and Tuple2 )
scala> Tuple2(1,2) == Pair(1,2)
res4: Boolean = true

scala> Pair(1,2) == (1,2)
res5: Boolean = true

scala> (1,2) == 1 -> 2
res6: Boolean = true


5)) what is Map[K, V]  -- Key and value --> all of map type
scala> var p = Map(1 -> "David", 9 -> "Elwood")
p: scala.collection.immutable.Map[Int,java.lang.String] = Map((1,David), (9,Elwood))

// map add data
scala> p += 8 -> "Archers"

scala> p
res23: scala.collection.immutable.Map[Int,java.lang.String] = Map((1,David), (9,Elwood), (8,Archers))

// map get data
scala> p.get(88)
res26: Option[java.lang.String] = None

scala> p.get(8)
res27: Option[java.lang.String] = Some(Archers)

// map get or else
scala> p.getOrElse(8, "no Data")
res29: java.lang.String = Archers

scala> p.getOrElse(88, "no Data")
res30: java.lang.String = no Data

// loop Key
scala> 1 to 8 map(p.get)
res36: scala.collection.immutable.IndexedSeq[Option[java.lang.String]] = 
Vector(Some(David), None, None, None, None, None, None, Some(Archers))

scala> 1 to 8 flatMap(p.get)
res34: scala.collection.immutable.IndexedSeq[java.lang.String] = 
Vector(David, Archers)

// map delete data
scala> p -= 9

scala> p
res38: scala.collection.immutable.Map[Int,java.lang.String] = Map((1,David), (8,Archers))

// map key find
scala> p.contains(8)
res44: Boolean = true

// max key value
scala> p.keys.reduceLeft(_ max _)
res46: Int = 9

// reduceLeft (key's max value)
scala> p.values
res47: Iterable[java.lang.String] = MapLike(David, Archers, john)

scala> p.values.reduceLeft((a, b) => if (a > b) a else b)
res48: java.lang.String = john

// map value find
scala> p.values.exists(_.contains("john"))
res65: Boolean = true

scala> p.values.exists(_.contains("charlse"))
res66: Boolean = false

// mapdata + mapdata
scala> p ++= List(5 -> "Cat", 6 -> "kirin")

scala> p
res72: scala.collection.immutable.Map[Int,java.lang.String] = 
Map((5,Cat), (1,David), (6,kirin), (9,john), (13,youngs), (8,Archers), (4,jason))

// mapdata - mapdata
scala> p
res72: scala.collection.immutable.Map[Int,java.lang.String] = 
Map((5,Cat), (1,David), (6,kirin), (9,john), (13,youngs), (8,Archers), (4,jason))

scala> p --= List(13,4)
scala> p
res74: scala.collection.immutable.Map[Int,java.lang.String] = 
Map((5,Cat), (1,David), (6,kirin), (9,john), (8,Archers))

scala> def removeInvalid(in: Map[Int, Person]) = in.filter(kv => kv._2.valid)
removeInvalid: (in: Map[Int,Person])scala.collection.immutable.Map[Int,Person]

6)) what is Option[T]
scala> import java.lang.{Boolean => JBool}
import java.lang.{Boolean=>JBool}

scala> def tryo[T](f: => T): Option[T] = try { Some(f)} catch { case _ => None }
tryo: [T](f: => T)Option[T]

scala> def toInt(s: String): Option[Int] = tryo(s.toInt)                        
toInt: (s: String)Option[Int]

scala> def toBool(s: String) = tryo(JBool.parseBoolean(s))                      
toBool: (s: String)Option[Boolean]

scala> def personFromParams(p: Map[String, String]): Option[Person] =
     for {name <- p.get("name")
       ageStr <- p.get("age")
       age <- toInt(ageStr)
       validStr <- p.get("valid")
       valid <- toBool(validStr)}
       yield new Person(age, first, valid)

// Some and getOrElse
scala> Some(3).get
res5: Int = 3

scala> None.get
java.util.NoSuchElementException: None.get

scala> None.getOrElse(123)
res12: Int = 123


---- XML Crreation and Manipulation ----
1)) basic
scala> <b>hello Xmls</b>
res14: scala.xml.Elem = <b>hello Xmls</b>

2)) xml multiple lines <span>

scala> <b id="hellos">                  
     | <span>hello hell WORLD!!!        
     | asdasdasd
     | </span>
     | </b>
res16: scala.xml.Elem = 
<b id="hellos">
<span>hello hell WORLD!!!
asdasdasd
</span>
</b>

3)) xml len
scala> def len(seq: Seq[_]) = seq.length
len: (seq: Seq[_])Int

scala> len(<b>hello</b><b>hello2</b>)   
res18: Int = 2

4)) xml in var data
scala> def now = System.currentTimeMillis.toString
now: java.lang.String

scala> <b time={now}>Hello man</b>
res20: scala.xml.Elem = <b time="1284550763149">Hello man</b>

// isOdd Xml express change
scala> def isOdd(in: Long) = in % 2L == 1L
isOdd: (in: Long)Boolean

scala> import scala.xml._
import scala.xml._

scala> def oddTime: Option[NodeSeq] = System.currentTimeMillis match {
     | case t if isOdd(t) => Some(Text(t.toString))
     | case _ => None 
     | }
oddTime: Option[scala.xml.NodeSeq]

scala> <b time={oddTime}>Sometimes</b>
res31: scala.xml.Elem = <b time="1284551334717">Sometimes</b>

scala> <b time={oddTime}>Sometimes</b>
res32: scala.xml.Elem = <b >Sometimes</b>

scala> <stuff>
     | {(1 to 3).map(i => <v id={i.toString}></v>)}
     | </stuff>
res37: scala.xml.Elem = 
<stuff>
<v id="1"></v><v id="2"></v><v id="3"></v>
</stuff>

scala> <stuff>{if (true) "dogs"}</stuff>
res38: scala.xml.Elem = <stuff>dogs</stuff>

scala> val info = """
     | var x = "";
     | if (true '' false) alert('Woof');
     | """
info: java.lang.String = 

var x = "";
if (true '' false) alert('Woof');
// PCData
scala> <script>{PCData(info)}</script>
res45: scala.xml.Elem = 
<script><![CDATA[
var x = "";
if (true '' false) alert('Woof');
]]></script>

// load xml ( xmlload)
scala> import scala.xml._
import scala.xml._

scala> val xml = XML.load("http://twib.jp/rss")

scala> xml \\ "title"

scala> (xml \\ "title").length  
res54: Int = 21

// simply xml Declaration
scala> val x2 = <x>{(1 to 3).map(i => <i>{i}</i>)}</x>
x2: scala.xml.Elem = <x><i>1</i><i>2</i><i>3</i></x>

scala> x2 \ "i"
res66: scala.xml.NodeSeq = NodeSeq(<i>1</i>, <i>2</i>, <i>3</i>)

scala> (x2 \ "i").map(_.text)
res67: scala.collection.immutable.Seq[String] = List(1, 2, 3)

scala> (x2 \ "i").map(_.text.toInt)     
res71: scala.collection.immutable.Seq[Int] = List(1, 2, 3)

scala> (x2 \ "i").map(_.text.toInt).foldLeft(0)(_ + _)
res73: Int = 6

// Modifyung xml
scala> import scala.xml._
import scala.xml._

scala> import scala.xml.transform._
import scala.xml.transform._

scala> val xmlBooks =       
     | <books instruction="update">
     | <book instruction="remove" name="book1" status="" />
     | <book instruction="add" name="book2" status="" />
     | </books>
xmlBooks: scala.xml.Elem = 
<books instruction="update">
<book instruction="remove" status="" name="book1"></book>
<book instruction="add" status="" name="book2"></book>
</books>

// remove Xml Node
val removeIt = new RewriteRule {
     |   override def transform(n: Node): NodeSeq = n match {
     |     case e: Elem if (e \ "@instruction").text == "remove" => NodeSeq.Empty
     |     case n => n
     |   }
     | }
removeIt: scala.xml.transform.RewriteRule{def transform(n: scala.xml.Node): scala.xml.NodeSeq} = <function1>

scala> new RuleTransformer(removeIt).transform(xmlBooks)
res74: Seq[scala.xml.Node] = 
<books instruction="update">

<book instruction="add" status="" name="book2"></book>
</books>

// add Xml Node
scala> val addIt = new RewriteRule {
     | override def transform(n: Node): NodeSeq = n match {
     | case e: Elem if (e \ "@instruction").text == "add" =>
     | new Elem(e.prefix, e.label, e.attributes.remove("instruction"), 
     | e.scope,
     | transform(e.child) ++ <added>I added this</added> :_*)
     | case n => n
     | }
     | }
addIt: scala.xml.transform.RewriteRule{def transform(n: scala.xml.Node): scala.xml.NodeSeq} = <function1>

scala> new RuleTransformer(addIt).transform(xmlBooks)
res77: Seq[scala.xml.Node] = 
<books instruction="update">
<book instruction="remove" status="" name="book1"></book>
<book status="" name="book2"><added>I added this</added></book>
</books>

// add and remove xml
scala> new RuleTransformer(addIt, removeIt).transform(xmlBooks)
res79: Seq[scala.xml.Node] = 
<books instruction="update">

<book status="" name="book2"><added>I added this</added></book>
</books>

---- Concurrency Without Synchronization ----
import java.util.concurrent.atomic.{AtomicReference => AtomR, AtomicLong}
import java.util.Random
import scala.collection.immutable.TreeHashMap

object Multics {
  // MT 型の定義。type を定義することで、タイピングの量が減らせる
  type MT = Map[String, Int]

  // 変数 info は イミュータブルな Map を保持する AtomicReference
  // AtomicReference は、同期化せずにどのスレッドからも更新ができる
  val info: AtomR[MT] = new AtomR(TreeHashMap.empty)
  // clashCnt は、AtomicLong で、スレッドが info への書き込みを行おうとして失敗した回数を保持する。
  // clashCnt は、同期化なしで、インクリメントできる
  val clashCnt = new AtomicLong

  // 新しいスレッドを作成し、repeatEvery のブロックを実行する。
  // repeatEvery(1000) は 1000 ミリ秒待ち、その後ブロックを実行する。
  // ブロックでは、clashCnt と info が持つ値の合計を出力する。
  // 同期処理なしで、info が持つ Map にアクセスできる。
  // Map はイミュータブルデータ型であり、変更されないことが分かっているからです。
  def main(arfv: Array[String]) {
    runThread {
      repeatEvery(1000) {
        println("Clash Count: " + clashCnt + " Total: " + info.get.foldLeft(0)(_ + _._2))
      }
    }

    // 次に、2000 スレッドを作成する
    for (i <- 1 to 2000) runThread {
      var cnt = 0
      val ran = new Random
      val name = "K" + i

      doSet(info) {old => old + (name -> 0)}
      // ループ処理を行う。それぞれのループ処理の中で、0から100ミリ秒間のランダムな待ち時間を設定する
      repeatEvery(ran.nextInt(100)) {
        doSet(info) {old => old + (name -> (old(name) + 1))}
        // スレッドに紐つけられているカウントを、インクリメントする
        cnt = cnt + 1
        // スレッドローカルのカウントと info の値が一致しなければ、並行処理に問題が発生したことになるため、例外の送出
        if (cnt != info.get()(name))
          throw new Exception("Thread: " + name + " failed")
      }
    }
  }

  // 新しいスレッドを作り、run メソッドに関数 f を設定後、スレッドを開始する。
  // スレッドの run メソッドが呼ばれると、関数 f が実行される。これはコードブロックを引数として渡す例。
  def runThread(f: => Unit) = (new Thread(new Runnable {def run(): Unit = f})).start

  // 同期処理なしで atom にアトミックな更新を行う。
  // 古い値を読み取り、update メソッドへ引数として渡し、
  // アトミックな更新を行います。
  // アトミックな更新が成功すれば(古い値は処理中に更新されません)、
  // 更新は最新バージョンのデータに対して行われ、更新は成功したことになる。
  // compareAndSet メソッドが失敗したら、clashCnt をインクリメントし、再度更新を試みる
  def doSet[T](atom: AtomR[T]) (update: T => T) {
    val old = atom.get
    if (atom.compareAndSet(old, update(old))) ()
    else {
      clashCnt.incrementAndGet
      doSet(atom)(update)
    }
  }

  // repeatEvery メソッドが制御フローの役割を果たす
  // repeatEvery は len と body の2つの引数を取り、
  // どちらも名前渡しです。repeatEvery のブロック内で参照されるたびに
  // 名前渡しで受け取ったコードが実行される
  def repeatEvery(len: => Int) (body: => Unit): Unit = {
    try {
      while(true) {
        Thread.sleep(len)
        body
      }
    } catch {
      case e => e.printStackTrace; System.exit(1)
    }
  }
}


----- Fun with Functions, and Never Having to Close That JDBC Connection -----

---- A function Is an Instance ----
scala> val f: Int => String = x => "Dude: "+x
f: (Int) => String = <function1>

scala> f(55)
res5: String = Dude: 55

scala> def w42(f: Int => String) = f(42)
w42: (f: (Int) => String)String

scala> w42(f)
res6: String = Dude: 42

scala> def fm(i: Int) = "fm "+i
fm: (i: Int)java.lang.String

scala> w42((i: Int) => fm(i))
res7: String = fm 42

---- Partial Application and Functions ----
scala> def plus(a: Int, b:Int) = "result is: "+(a + b)
plus: (a: Int,b: Int)java.lang.String

scala> plus(4,2) 
res13: java.lang.String = result is: 6

cala> val p = (b: Int) => plus(42, b)
p: (Int) => java.lang.String = <function1>

scala> p(4)
res15: java.lang.String = result is: 46

scala> def add(a:Int, b:Int)(c:Int) = "Result is: " + a + " " + b + " " + c
add: (a: Int,b: Int)(c: Int)java.lang.String

scala> add(19, 29)(38)
res18: java.lang.String = Result is: 19 29 38

// function and add function
scala> def add(a:Int)(b: Int) = "Result is "+ (a + b)
add: (a: Int)(b: Int)java.lang.String

scala> add(1)(2)
res25: java.lang.String = Result is 3

scala> add(1) {
     | var r= new java.util.Random
     | r.nextInt(100)
     | }
res26: java.lang.String = Result is 56

scala> w42(add(1))   
res27: String = Result is 43

scala> def f2 = add(1) _
f2: (Int) => java.lang.String

scala> w42 (f2)
res33: String = Result is 43

--- Functions and Type Parameters ---
scala> f(42)
res34: String = Dude: 42

scala> def t42[T](f: Int => T): T = f(42)
t42: [T](f: (Int) => T)T

scala> t42(f)
res35: String = Dude: 42

// input valList
scala> val intList: Int => List[Int] = i => (1 to i).toList
intList: (Int) => List[Int] = <function1>

scala> t42(intList)
res41: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42)

scala> t42[Int](1 +)
res42: Int = 43

--- Functions Bound to Variables in Scope ---
scala> val foo = "dog"
foo: java.lang.String = dog

scala> val whoTo = (s: String) => s+ " "+foo
whoTo: (String) => java.lang.String = <function1>

scala> whoTo("I Love man")
res45: java.lang.String = I Love man dog

scala> var strs: List[String] = Nil
strs: List[String] = List()

scala> val strF = (s: String) => {strs ::= s; s+ " Registered"}
strF: (String) => java.lang.String = <function1>

scala> strF("a")
res46: java.lang.String = a Registered

scala> strF("b")
res47: java.lang.String = b Registered

scala> strs
res48: List[String] = List(b, a)

scala> 

scala> List("p", "q", "r").map(strF)
res49: List[java.lang.String] = List(p Registered, q Registered, r Registered)

scala> strs
res51: List[String] = List(r, q, p, b, a)

--- Putting Functions in Containers ---
scala> def bf: Int => Int => Int = i => v => i + v
bf: (Int) => (Int) => Int

scala> val fs = (1 to 100).map(bf).toArray
fs: Array[(Int) => Int] = Ar...

scala> fs(0)(1)
res58: Int = 2

scala> fs(44)(3)
res59: Int = 48

--- Functions and Interactive Applications ---
scala> def randomName = "I"+Math.abs((new java.util.Random).nextLong)
randomName: java.lang.String

scala> trait JavaScript
defined trait JavaScript

scala> var callbacks: Map[String, () => JavaScript] = Map()
callbacks: Map[String,() => JavaScript] = Map()

scala> def register(f: () => JavaScript) = {
     | val name = randomName
     | callbacks += name -> f
     | <button onclick={"invokeSeverCall('"+ name+"')"}>ClcikMe</button>
     | }
register: (f: () => JavaScript)scala.xml.Elem


--- Building New Function ---
scala> sealed trait Expr
defined trait Expr

scala> case class Add(left: Expr, right: Expr) extends Expr
defined class Add

scala> case class Mul(left: Expr, right: Expr) extends Expr
defined class Mul

scala> case class Val(value: Int) extends Expr
defined class Val

scala> case class Var(name: String) extends Expr
defined class Var

scala> def calc(expr: Expr, vars: Map[String, Int]): Int = expr match {
     | case Add(left, right) => calc(left, vars) + calc(right, vars)
     | case Mul(left, right) => calc(left, vars) * calc(right, vars)
     | case Val(v) => v
     | case Var(name) => vars(name)
     | }
calc: (expr: Expr,vars: Map[String,Int])Int

scala> def buildCalc(expr: Expr): Map[String, Int] => Int = expr match {
     | case Add(left, right) =>
     | val lf = buildCalc(left)
     | val rf = buildCalc(right)
     | m => lf(m) + rf(m)
     | 
     | case Mul(left, right) =>
     | val lf = buildCalc(left)
     | val rf = buildCalc(right)
     | m => lf(m) * rf(m)
     | 
     | case Val(v) => m => v
     | case Var(name) => m => m(name)
     | }

--- call-by-name, call-by-value, and General Laziness ---
scala> def allStrings(expr: => String): List[String] = expr match {
     | case null => Nil                                            
     | case s => s :: allStrings(expr)                             
     | }                                                           
allStrings: (expr: => String)List[String]

scala> import java.io._
import java.io._

scala> val br = new BufferedReader(new FileReader("foo.txt"))
br: java.io.BufferedReader = java.io.BufferedReader@5f08edd0

scala> allStrings(br.readLine)
res9: List[String] = List(test file, hello secnod line, 3 line)

---- Pattern Matching ----
scala> def fibonacci(in: Int): Int = in match {    
     | case 0 => 0                                 
     | case 1 => 1                                 
     | case n => fibonacci(n - 1) + fibonacci(n -2)
     | }
fibonacci: (in: Int)Int

scala> fibonacci(8)
res0: Int = 21

scala> def fib2(in: Int): Int = in match {
     | case n if n <= 0 => 0
     | case 1 => 1
     | case n => fib2(n - 1) + fib2(n - 2)
     | }
fib2: (in: Int)Int

scala> fib2(4)
res3: Int = 3

--- matching any type ---
scala> def MyMules(name: String) = name match {
     | case "Elwood" | "Madeline" => Some("cat")
     | case "Archer" => Some("Dog")
     | case "Pumpking" | "Firetruc" => Some("Fish")
     | case _ => None
     | }
MyMules: (name: String)Option[java.lang.String]

scala> MyMules("Elwood")
res0: Option[java.lang.String] = Some(cat)

scala> object MyMules {
     | def myMules(name: String) = name match {
     | case "Elwood" | "Madeline" => Some("Cat")
     | case "Archer" => Some("Dog")
     | case "Pumpkin" | "Firetruck" => Some("Fish")
     | case _ => None
     | }
     | }
defined module MyMules

scala> MyMules.myMules("Elwood")
res6: Option[java.lang.String] = Some(Cat)

--- Testing Data Type ---
scala> def test2(in : Any) = in match {
     | case s: String => "String, Length "+ s.length
     | case i: Int if i > 0 => "Natural Int"
     | case i: Int => "Another Int"
     | case a: AnyRef => a.getClass.getName
     | case _ => "null"
     | }
test2: (in: Any)java.lang.String

scala> test2("s")
res7: java.lang.String = String, Length 1

scala> test2(0)
res8: java.lang.String = Another Int

scala> test2(4)
res9: java.lang.String = Natural Int

scala> test2(MyMules)
res10: java.lang.String = MyMules$

--- case classes ---
scala> case class Person(name: String, age: Int, valid: Boolean)
defined class Person

// default name, age, valid = Val
scala> case class Person(var name: String, var age: Int, var valid: Boolean)
defined class Person

scala> val mp = MPerson("jorge", 24) 
mp: MPerson = MPerson(jorge,24)

scala> mp.age = 25

scala> mp
res13: MPerson = MPerson(jorge,25)

scala> def older(p: Person): Option[String] = p match {
     | case Person(name, age, true) if age > 35 =>Some(name)
     | case _ => None
     | }
older: (p: Person)Option[String]

scala> older(p)
res15: Option[String] = Some(David)

scala> older(Person("Frank", 30, true)) 
res20: Option[String] = None

scala> older(Person("Frank", 40, true))
res21: Option[String] = Some(Frank)

scala> older(Person("Frank", 40, false))
res22: Option[String] = None

--- Pattern Matching ---
scala> val x = 1
x: Int = 1

scala> val rest = List(2,3,4)
rest: List[Int] = List(2, 3, 4)

scala> x :: rest
res23: List[Int] = List(1, 2, 3, 4)

scala> x :: x :: rest
res24: List[Int] = List(1, 1, 2, 3, 4)

scala> (x :: rest) match {                                            
     | case xprime :: restprime => println(xprime); println(restprime)
     | }
1
List(2, 3, 4)

-- patern matching and lists --
scala> def sumOdd(in: List[Int]): Int = in match{
     | case Nil => 0
     | case x :: rest if x % 2 == 1 => x + sumOdd(rest)
     | case _ :: rest => sumOdd(rest)
     | }
sumOdd: (in: List[Int])Int

scala> sumOdd(rest)
res27: Int = 3

scala> rest
res28: List[Int] = List(2, 3, 4)

scala> sumOdd(x :: rest)
res29: Int = 4

scala> def noPairs[T](in:List[T]): List[T] = in match {            
     | case Nil => Nil
     | case a :: b :: rest if a == b => noPairs(a :: rest)
     | case a :: rest => a :: noPairs(rest)
     | }
noPairs: [T](in: List[T])List[T]

scala> noPairs(List(1,2,3,3,3,4,1,1))
res30: List[Int] = List(1, 2, 3, 4, 1)

scala> def ignore(in: List[String]): List[String] = in match {
     | case Nil => Nil
     | case _ :: "ignore" :: rest => ignore(rest)
     | case x :: rest => x :: ignore(rest)
     | }
ignore: (in: List[String])List[String]

scala> def getStrings(in: List[Any]): List[String] = in match {
     | case Nil => Nil
     | case (s: String) :: rest => s :: getStrings(rest)
     | case _ :: rest => getStrings(rest)
     | }
getStrings: (in: List[Any])List[String]

scala> val xxx = List("a", 1, "b", 2L) 
xxx: List[Any] = List(a, 1, b, 2)

scala> getStrings(xxx)
res33: List[String] = List(a, b)


--- Nested Pattern Matching in case classes ---
scala> case class MarriedPerson(override val name: String,
     | override val age: Int,
     | override val valid: Boolean,
     | spouse: Person) extends Person(name, age, valid)
defined class MarriedPerson

scala> def mOlder(p: Person): Option[String] = p match {
     | case Person(name, age, true) if age > 35 => Some(name)
     | case MarriedPerson(name, _, _, Person(_, age, true))
     | if age > 35 => Some(name)
     | case _ => None
     | }
mOlder: (p: Person)Option[String]

scala> mOlder(p)
res36: Option[String] = Some(David)

scala> mOlder(sally)
res37: Option[String] = Some(sally)

--- Pattern Matching as Functions ---
scala> val list=List("aa", "bb", "cc", "dd", 11)
list: List[Any] = List(aa, bb, cc, dd, 11)

scala> list.filter(a => a match {               
     | case s: String => true                   
     | case _ => false                          
     | })                                       
res40: List[Any] = List(aa, bb, cc, dd)

scala> def handleRequest(req: List[String])(                       
     | exceptions: PartialFunction[List[String], String]): String =
     | if (exceptions.isDefinedAt(req)) exceptions(req) else       
     | "Handling URL "+ req+ " in the normal way"                  
handleRequest: (req: List[String])(exceptions: PartialFunction[List[String],String])String

scala> def doApi(call: String, params: List[String]): String =
     | "Doing Api Call" + call
doApi: (call: String,params: List[String])String

scala> handleRequest("foo" :: Nil) {                          
     | case "api" :: call :: params => doApi(call, params)    
     | }                                                      
res45: String = Handling URL List(foo) in the normal way


---- 다음 화에 계속..

다음화에서는 OOP라던지 Actor 등을 나열해 보도록 하겠습니다. 그럼 다음 기회에 :)