Created
November 8, 2011 01:00
-
-
Save monzou/1346713 to your computer and use it in GitHub Desktop.
Scala School
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package school | |
object ScalaSchoolAdvancedTypes { | |
implicit def strToInt(x: String) = x.toInt | |
/* | |
* クラスの型パラメータ | |
* | |
* A <% B : A が B として見れる | |
* +A : A と A のサブクラス | |
* -A : A と A のスーパークラス | |
*/ | |
class Container[A <% Int] { def addIt(x: A) = 123 + x } // A は Int として見ることが出来る必要があることを示すコンテナ | |
/* | |
* メソッドの型パラメータ | |
* | |
* A => B : A は B として見れる | |
* A =:= B : A と B が等しい | |
* A <:< B : A は B のサブクラス | |
*/ | |
class Container2[A](value: A) { | |
def add1(implicit evidence: A =:= Int) = 123 + value // A は Int と同じである必要がある | |
def add2(implicit evidence: A => Int) = 123 + value // A は Int として見ることが出来る必要がある | |
} | |
def main(args: Array[String]) { | |
val y = "123" // implicit | |
println((new Container[Integer]).addIt(123)) | |
println((new Container[String]).addIt("123")) // implicit | |
// println((new Container[Double]).addIt(123d)) // Double は Int として見れない | |
def maxList[T](elements: List[T])(implicit orderer: T => Ordered[T]): T = { // implicit な ordered を与えられる | |
elements match { | |
case List() => throw new IllegalArgumentException("empty list") | |
case List(x) => x | |
case x :: rest => { | |
val maxRest = maxList(rest) | |
if (x > maxRest) x else maxRest | |
} | |
} | |
} | |
println(maxList((List(1, 2, 3)))) | |
println(maxList((List("1", "2", "3")))) // implicit | |
val c = new Container2("150") | |
// c.add1 // String のコンテナなので, add1 の引数は String と同じ型である必要がある | |
println(c.add2) // String は Int に implicit されるので OK | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package school | |
object ScalaSchoolAdvancedTypes2 { | |
// 高階型(M は任意の型パラメータを必要とする) | |
trait Container[M[_]] { | |
def put[A](x: A): M[A] | |
def get[A](m: M[A]): A | |
} | |
def main(args: Array[String]) { | |
// List の型パラメータについてポリモーフィックに振る舞うコンテナ | |
val c = new Container[List] { | |
def put[A](x: A) = List(x) | |
def get[A](m: List[A]) = m.head | |
} | |
println(c.put("hey")) | |
println(c.get(List(1, 2, 3))) | |
// 暗黙的なコンビネータを定義して汎用的な Container に対する関数定義を行う | |
implicit val listContainer = new Container[List] { | |
def put[A](x: A) = List(x) | |
def get[A](m: List[A]) = m.head | |
} | |
implicit val optionContainer = new Container[Some] { | |
def put[A](x: A) = Some(x) | |
def get[A](m: Some[A]) = m.get | |
} | |
def tuplize[M[_]: Container, A, B](fst: M[A], snd: M[B]) = { | |
val c = implicitly[Container[M]] // Container[M] に対して implict 定義されたコンビネータを取得 | |
c.put(c.get(fst), c.get(snd)) | |
} | |
println(tuplize(Some(1), Some(2))) | |
println(tuplize(List(1, 2), List(3, 4))) | |
// println(tuplize(Set(1), Set(2))) // implicit されてないのでエラー | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package school | |
object ScalaSchoolAdvancedTypes3 { | |
def main(args: Array[String]) { | |
// Int を返す get メソッドを持つ構造型 | |
// これはリフレクションを用いるのでパフォーマンスに注意 | |
def foo(x: { def get: Int }) = 123 + x.get | |
println(foo(new { def get = 10 })) | |
// type 変数 | |
trait Foo { | |
type A | |
val x: A | |
def getX: A = x | |
} | |
println(new Foo { type A = Int; val x = 123 }.getX) | |
println(new Foo { type A = String; val x = "123" }.getX) | |
// コンテナでも使える | |
trait Bar[M[_]] { type t[A] = M[A] } | |
val x: Bar[List]#t[Int] = List(1) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package school | |
object ScalaSchoolBasics { | |
def main(args: Array[String]) { | |
val add2 = adder(2, _: Int) | |
val five = add2(3) | |
println(five) | |
println(multiply(2)(3)) | |
val timesTwo = multiply(2)(_) | |
println(timesTwo(3)) | |
val f1 = (adder(_, _)) | |
println(f1) | |
println(f1(2, 3)) | |
val f2 = (adder(_, _)).curried | |
println(f2) | |
println(f2(2)(3)) | |
println(capitalizeAll("hello", "world")) | |
val calc = new Calculator("hello") | |
println(calc.brand) | |
println(calc.add(1, 2)) | |
println(Bar("hoge")) | |
val cc1 = CC("HP", "type-1") | |
val cc2 = CC("HP", "type-1") | |
val cc3 = CC("HP", "type-2") | |
val cc4 = CC("BMW", "type-1") | |
println(cc1 == cc2) | |
println(cc3 == cc2) | |
println(cc4 == cc2) | |
println(cMatch(cc1)) | |
println(cMatch(cc2)) | |
println(cMatch(cc3)) | |
println(cMatch(cc4)) | |
try { | |
} catch { | |
case e: Exception => System.err.println("error"); | |
} finally { | |
} | |
} | |
def adder(m: Int, n: Int) = m + n | |
def multiply(m: Int)(n: Int) = m * n | |
def capitalizeAll(args: String*) = { | |
args.map { arg => arg.capitalize } | |
} | |
class Calculator(_brand: String) { | |
val brand = _brand | |
def add(m: Int, n: Int) = m + n | |
} | |
trait Car { | |
val brand: String | |
} | |
class BMW extends Car { | |
val brand = "BMW" | |
} | |
class Bar(foo: String) | |
object Bar { | |
def apply(foo: String) = new Bar(foo) | |
} | |
case class CC(brand: String, model: String) | |
def cMatch(cc: CC) = cc match { | |
case CC("HP", "type-1") => "TYPE I" | |
case CC("HP", _) => "HP" | |
case _ => "OTHER" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package school | |
object ScalaSchoolCollections { | |
def main(args: Array[String]) { | |
val numbers = List(1, 2, 3) | |
val host = ("localhost", 8080) | |
println(host._1) | |
println(host._2) | |
val host2 = "http://google.com" -> 9080 | |
List(host, host2) foreach (h => | |
h match { | |
case ("localhost", port) => println(port) | |
case _ => println("others") | |
}) | |
val map1 = Map(1 -> Map(1 -> "hoge"), 2 -> Map(2 -> "fuga")) | |
println(map1) | |
println(map1.get(1)) | |
println(map1.get(2)) | |
println(map1.get(3)) | |
// map returns value | |
println(numbers.map(i => i * 2)) | |
def timesTwo(i: Int) = i * 2 | |
println(numbers.map(timesTwo _)) | |
// foreach returns nothing | |
println(numbers.foreach(i => i * 2)) | |
def isEven(i: Int) = i % 2 == 0 | |
println(numbers.filter(isEven _)) | |
println(List(1, 2, 3, 4, 5, 6, 7).partition(i => i > 5)) | |
println(numbers.find(i => i == 2).get) | |
// println(numbers.find(i => i == 0).get) // throws exception | |
println(List(1, 2, 3, 4, 5).foldLeft("0")((sum, i) => sum + i)) // 左から畳み込む = 012345 | |
println(List(1, 2, 3, 4, 5).foldRight("0")((sum, i) => sum + i)) // 右から畳み込む = 123450 | |
def mapFunction(numbers: List[Int], fn: Int => Int): List[Int] = { | |
numbers.foldRight(List[Int]()) { (x: Int, xs: List[Int]) => | |
fn(x) :: xs | |
} | |
} | |
println(mapFunction(numbers, timesTwo _)) | |
val extensions = Map("steve" -> 100, "bob" -> 101, "joe" -> 201) | |
println(extensions.filter((namePhone: (String, Int)) => namePhone._2 < 200)) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package school | |
import scala.annotation.implicitNotFound | |
object ScalaSchoolPatternMatchingAndFunctionalComposition { | |
def main(args: Array[String]) { | |
def addUmm(x: String): String = x + " umm" | |
def addAhem(x: String): String = x + " ahem" | |
// val ummThenAhem = addAhem(_).compose(addUmm(_)) // エラーになる... | |
// val ahemThenUmm = addAhem(_).andThen(addUmm(_)) // エラーになる... | |
val ummThenAhem = (addAhem(_)).compose(addUmm) | |
println(ummThenAhem("well")) | |
val ahemThenUmm = (addAhem(_)).andThen(addUmm) | |
println(ahemThenUmm("well")) | |
val one: PartialFunction[Int, String] = { case 1 => "one" } | |
val two: PartialFunction[Int, String] = { case 2 => "two" } | |
val three: PartialFunction[Int, String] = { case 3 => "three" } | |
println(one(1)) | |
println(one.isDefinedAt(1)) | |
println(one.isDefinedAt(2)) | |
val oneTwoThree = one orElse two orElse three | |
println(oneTwoThree.isDefinedAt(1)) | |
println(oneTwoThree.isDefinedAt(2)) | |
println(oneTwoThree.isDefinedAt(3)) | |
case class PhoneExt(name: String, ext: Int) | |
val extensions = List(PhoneExt("steve", 100), PhoneExt("robey", 200)) | |
val filtered = extensions.filter { case PhoneExt(name, extension) => extension < 200 } | |
println(filtered) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment