Skip to content

Instantly share code, notes, and snippets.

@yuroyoro
Created September 5, 2012 03:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yuroyoro/3629938 to your computer and use it in GitHub Desktop.
Save yuroyoro/3629938 to your computer and use it in GitHub Desktop.
// カリー化された定義の利点その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