Created
September 5, 2012 03:35
-
-
Save yuroyoro/3629938 to your computer and use it in GitHub Desktop.
This file contains 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
// カリー化された定義の利点その1 | |
// 擬似的な制御構文を作るのに使える | |
// | |
// 以下の関数maybeは、maybe(条件){ 式 } のような使い方ができる。 | |
// 条件が真なら、式の実行結果をSomeに包んでSome[A]を返し、 | |
// 偽ならばNoneを返す | |
scala> def maybe[A](cond: => Boolean)(f: => A):Option[A] = if(cond) Some(f) else None | |
maybe: [A](cond: => Boolean)(f: => A)Option[A] | |
scala> maybe(true){ util.Random.nextPrintableChar } | |
res1: Option[Char] = Some(I) | |
scala> maybe(false){ util.Random.nextPrintableChar } | |
res2: Option[Char] = None | |
// カリー化された関数の利点その2 | |
// 部分適用した関数を、変数等に入れておくことで、再利用可能になる | |
// | |
// 以下のmaybeEvenは、maybeに、「Randomが偶数を返した場合……」という、 | |
// 第一引数で部分適用した状態の関数である。 | |
scala> val maybeEven = maybe {util.Random.nextInt % 2 == 0}(_:String) | |
maybeEven: String => Option[String] = <function1> | |
// このmaybeEvenを繰り返し、異なる式を与えて何度でも評価させることができる | |
scala> maybeEven("hoge") | |
res3: Option[String] = None | |
scala> maybeEven("( ゚∀゚)o彡°おっぱい!おっぱい!") | |
res4: Option[String] = None | |
scala> maybeEven("( ゚∀゚)o彡°おっぱい!おっぱい!") | |
res5: Option[String] = Some(( ゚∀゚)o彡°おっぱい!おっぱい!) | |
scala> maybeEven("hoge") | |
res6: Option[String] = Some(hoge) | |
scala> maybeEven("hoge") | |
res7: Option[String] = Some(hoge) | |
// カリー化された関数の利点その3 | |
// 部分適用した関数を、他の高階関数に渡すために使える | |
// | |
// Option[String]#flatMapは、引数に(String => Option[String])型の | |
// 関数を受け取る。 | |
// 以下の例は、Some("Oppai")をflatMapを使ってSome("Oppai!Oppai!")する例 | |
scala> Some("Oppai") flatMap{ s => Some((s + "!!") *2 ) } | |
res15: Option[String] = Some(Oppai!!Oppai!!) | |
// 先ほどのmaybeを使って、randomが偶数を返すときのみおっぱいおっぱいしたいとする。 | |
// maybeの型は、Boolean => A => Option[A]なので、そのままでは型が合わない | |
scala> Some("Oppai") flatMap{ s => Some((s + "!!") *2 ) } flatMap(maybe) | |
<console>:9: error: polymorphic expression cannot be instantiated to expected type; | |
found : [A]=> Boolean => => A => Option[A] | |
required: String => Option[?] | |
Some("Oppai") flatMap{ s => Some((s + "!!") *2 ) } flatMap(maybe) | |
^ | |
=> Boolean => => A => Option[A] <: String => Option[?]? | |
String <: => Boolean? | |
<notype> <: => Boolean? | |
false | |
<notype> <: => Boolean? | |
false | |
false | |
false | |
// 先ほどのmaybeEventのように、第一引数を部分適用して型パラメータAをStringに | |
// 束縛することで、(String => Option[String])型の関数オブジェクトを得ることが | |
// できるので、flatMapに渡すことができる。 | |
scala> Some("Oppai") flatMap{ s => Some((s + "!!") *2 ) } flatMap(maybeEven) | |
res16: Option[String] = Some(Oppai!!Oppai!!) | |
scala> Some("Oppai") flatMap{ s => Some((s + "!!") *2 ) } flatMap(maybeEven) | |
res17: Option[String] = Some(Oppai!!Oppai!!) | |
scala> Some("Oppai") flatMap{ s => Some((s + "!!") *2 ) } flatMap(maybeEven) | |
res18: Option[String] = None |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment