2012-10-05 Rubyの備忘録
2012-08-06 Scala Streamで無限に要素をもつコレクションをあつかう
Scala Streamで無限に要素をもつコレクションをあつかう
Stream - Scala Standard Library API (Scaladoc) 2.10.1 - scala.collection.immutable.Streamをつかうと、無限に要素をもつコレクションをあつかえるらしい。
実際のところは、要素の生成を後回しにして、無限の要素があるかのようにふるまうということらしい。
Javaだと、なつかしいところで、LazyList (Commons Collections 4.0-SNAPSHOT API)こんなのもつかったことあったなあ。
Streamもやっぱり、要素を生成する処理を記述して、使用する。
scala> def makeSameElement(x: Int): Stream[Int] = Stream.cons(x, makeSameElement(x)) makeSameElement: (x: Int)Stream[Int] scala> makeSameElement(1) take 10 res6: scala.collection.immutable.Stream[Int] = Stream(1, ?) scala> val a = makeSameElement(1) take 10 a: scala.collection.immutable.Stream[Int] = Stream(1, ?) scala> a foreach println 1 1 1 1 1 1 1 1 1 1
Stream.consは、#::でもよいらしい。
scala> def makeNaturalNumber(x: Int): Stream[Int] = x #:: makeNaturalNumber(x + 1) makeNaturalNumber: (x: Int)Stream[Int] scala> val b = makeNaturalNumber(1) take 10 b: scala.collection.immutable.Stream[Int] = Stream(1, ?) scala> b.foreach(println) 1 2 3 4 5 6 7 8 9 10 scala>
2012-08-05 Scala scala.util.Randomで乱数を生成する。
scala.util.Randomで乱数を生成する。
1から10までのランダムな数をつくるのはどうやるんだろう。
Random - Scala Standard Library API (Scaladoc) 2.10.1 - scala.util.Randomを見てみたが、おおむねjava.util.Randomとおなじか?
scala> import scala.util.Random import scala.util.Random scala> val r = new Random r: scala.util.Random = scala.util.Random@5f04eb scala> r.nextInt res173: Int = -49067135 scala> r.nextInt(10) res175: Int = 4 scala> r.nextInt(10) + 1 res176: Int = 1
ランダムな数字のリストがほしい
scala> r.shuffle((1 to 10).toSeq) res37: scala.collection.immutable.IndexedSeq[Int] = Vector(7, 4, 8, 9, 1, 3, 10, 5, 2, 6)
ちょっとちがうかな。
こうかなあ
scala> def r10 = r.nextInt(10) + 1 r10: Int scala> r10 res168: Int = 10 scala> r10 res169: Int = 1 scala> def infinitR10: Stream[Int] = Stream.cons(r10, infinitR10) infinitR10: Stream[Int] scala> infinitR10 take 20 res171: scala.collection.immutable.Stream[Int] = Stream(6, ?) scala> infinitR10 take 20 foreach println 10 2 1 8 6 6 4 8 5 4 9 7 10 2 6 7 6 2 4 10 scala>
あれ?なんか数が偏っている?一様になってないかな。うーん。集計してみる。
scala> b.foldLeft (Map[Int, Int]()) { (acc: Map[Int, Int], e: Int) =>
| acc + (e -> (acc.getOrElse(e, 0) + 1))
| }
res208: scala.collection.immutable.Map[Int,Int] = Map(5 -> 6, 1 -> 1, 6 -> 2, 9 -> 3, 2 -> 2, 7 -> 1, 3 -> 1, 8 -> 2, 4 -> 2)
scala> val c = infinitR10 take 10000
c: scala.collection.immutable.Stream[Int] = Stream(4, ?)
scala> c.foldLeft (Map[Int, Int]()) { (acc: Map[Int, Int], e: Int) =>
| acc + (e -> (acc.getOrElse(e, 0) + 1))
| }
res209: scala.collection.immutable.Map[Int,Int] = Map(5 -> 1038, 10 -> 1028, 1 -> 964, 6 -> 1008, 9 -> 1011, 2 -> 1018, 7 -> 1009, 3 -> 1000, 8 -> 930, 4 -> 994)
もっと多くのデータで!
ヒープのサイズを増やして、ScalaのREPLを起動しなおす。
F:\Data\ProgrammingLanguage\Scala\play-projects>scala -DXmx1024m
Welcome to Scala version 2.9.0.1 (Java HotSpot(TM) Client VM, Java 1.7.0_02).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scala.util.Random
import scala.util.Random
scala> val r = new Random
r: scala.util.Random = scala.util.Random@d7ba5b
scala> def r10 = r.nextInt(10) + 1
r10: Int
scala> def infinitR10: Stream[Int] = Stream.cons(r10, infinitR10)
infinitR10: Stream[Int]
scala> val d = infinitR10 take 1000000
d: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> val result = d.foldLeft (Map[Int, Int]()) { (acc: Map[Int, Int], e: Int) =>
| acc + (e -> (acc.getOrElse(e, 0) + 1))
| }
result: scala.collection.immutable.Map[Int,Int] = Map(5 -> 100161, 10 -> 99790, 1 -> 99934, 6 -> 99675, 9 -> 99919, 2 -> 99738, 7 -> 99758, 3 -> 100131, 8 -> 100429, 4 -> 100465)
scala> import scala.collection.immutable.TreeMap
import scala.collection.immutable.TreeMap
scala> val result2 = TreeMap[Int, Int]()
result2: scala.collection.immutable.TreeMap[Int,Int] = Map()
scala> result2 ++ result
res6: scala.collection.immutable.TreeMap[Int,Int] = Map(1 -> 99934, 2 -> 99738, 3 -> 100131, 4 -> 100465, 5 -> 100161, 6 -> 99675, 7 -> 99758, 8 -> 100429, 9 -> 99919, 10 -> 99790)
scala>
さらに要素の数を1000000から10000000にしたら、Out Of Memoryになってしまった。そうならないためのStreamではないのか?自分がなにかまちがっているのか。うーん。。。。
Stream - Scala Standard Library API (Scaladoc) 2.10.1 - scala.collection.immutable.Streamにある例のIteratorを使う方法を試してみる。
scala> import scala.util.Random
import scala.util.Random
scala> val r = new Random
r: scala.util.Random = scala.util.Random@d7ba5b
scala> def r10 = r.nextInt(10) + 1
r10: Int
scala> val it = new Iterator[Int] {
| def hasNext = true
| def next: Int = { r10 }
| }
it: java.lang.Object with Iterator[Int] = non-empty iterator
scala> val d = it take 100000000
d: Iterator[Int] = non-empty iterator
scala> val result = d.foldLeft (Map[Int, Int]()) { (acc: Map[Int, Int], e: Int) =>
| acc + (e -> (acc.getOrElse(e, 0) + 1))
| }
result: scala.collection.immutable.Map[Int,Int] = Map(5 -> 9999613, 10 -> 9998925, 1 -> 10005035, 6 -> 10004810, 9 -> 9992785, 2 -> 9995009, 7 -> 9999772, 3 -> 10002721, 8 -> 10000349, 4 -> 10000981)
scala> import scala.collection.immutable.TreeMap
import scala.collection.immutable.TreeMap
scala> val result2 = TreeMap[Int, Int]()
result2: scala.collection.immutable.TreeMap[Int,Int] = Map()
scala> result2 ++ result
res7: scala.collection.immutable.TreeMap[Int,Int] = Map(1 -> 10005035, 2 -> 9995009, 3 -> 10002721, 4 -> 10000981, 5 -> 9999613, 6 -> 10004810, 7 -> 9999772, 8 -> 10000349, 9 -> 9992785, 10 -> 9998925)
scala>
おおー、Iteratorだと、10000000どころか100000000でもだいじょうぶだ。
もはや、主題がRandomのはなしでなくなってしまったが、、、、Streamはつかいかたは、勉強だな。とりあえずは、Iteratorがお手軽だと。
2012-05-25
ScalaのcomposeとandThen
f(g(x))なのかg(f(x))なのかすぐにわすれちゃう。メモしておこう。
scala> val f = (x: Int) => 2 * x f: (Int) => Int = <function1> scala> val g = (x: Int) => x + 1 g: (Int) => Int = <function1> scala> f(g(1)) res9: Int = 4 scala> (f compose g)(1) res10: Int = 4 scala> g(f(1)) res11: Int = 3 scala> (f andThen g)(1) res12: Int = 3 scala>
2012-05-07 Scala PartialFunction 部分関数
Scala PartialFunction 部分関数
PartialFunction
- PartialFunction - Scala Standard Library API (Scaladoc) 2.10.1 - scala.PartialFunction
- Scaladocの例を見る限り、caseをつかうと、PartialFunctionを簡単に書けるのか。
- caseで指定された限られた範囲で、部分的に関数を定義しているってことだろうか。
- Inverse Fizzbuzz - just another scala quant
- FizzBuzzの実装だけど、PartialFunctionを使った実装がある。
- この例だと、複数のcaseを、isDefinedAtメソッドでひとつにまとめているように見える。
- Scala School - Pattern matching & functional composition
- 関数をうまいこと組み合わせるための方法
- Understanding PartialFunction
結局、部分関数とは、なんでしょう?
やっぱり、限られた範囲で定義した関数を、部分関数とよんでいるようだ。
自分の中で思い浮かんだ例としては、高校の数学でやった定義域のある関数を思い出した。
Scalaの部分関数というのは、定義域のある関数を表現するようなもののように見える。この定義域なら、こんな関数を適用する。この定義域でないなら、何もしない。それを表現するもの。
定義域X1で定義された関数はf, 定義域X2で定義された関数はg, 定義域X3で定義された関数はh,,,,のように、定義域ごとにバラバラに関数を定義するから、部分関数って表現なんだろうか。
そうすると、ScaladocPartialFunction - Scala Standard Library API (Scaladoc) 2.10.1 - scala.PartialFunctionの
- abstract def apply(v1: A): B
- Apply the body of this function to the argument.
- abstract def isDefinedAt(x: A): Boolean
- Checks if a value is contained in the function's domain.
というのも、そのまんま、しっくりくるかなあ。さらに、
- def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]): PartialFunction[A1, B1]
これも、f(X1)とg(X2)とh(X3)を、ひとつの関数にするものとして、ピンとくるな
あらためて、部分関数を調べてみると、プログラミングや情報科学ではなくて、数学の概念としてちゃんとあった
Function (mathematics) - Wikipedia, the free encyclopedia
これを見ると、部分関数というのは、定義域の一部に対して、定義されている関数のこというわけか。なるほどー。
関数型言語をやるときは、用語がどこに由来しているか、ちょっと調べるといいのかもな。そのプログラミング言語特有なのか、情報科学なのか、数学なのか。

