Skip to content

Instantly share code, notes, and snippets.

@monzou
Created November 8, 2011 01:00
Show Gist options
  • Save monzou/1346713 to your computer and use it in GitHub Desktop.
Save monzou/1346713 to your computer and use it in GitHub Desktop.
Scala School
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
}
}
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 されてないのでエラー
}
}
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)
}
}
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"
}
}
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))
}
}
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