遊んだ

久々に (?) Scala で遊んでみる。

  • 再帰さん
scala> def z[A,B](f: (A=>B) => (A=>B)): A=>B = (x:A) => f(z(f))(x)
z: [A,B](((A) => B) => (A) => B)(A) => B

scala> z { (f:Int=>Int) => (n:Int) => if (n < 2) n else n * f(n - 1) } (10)
res2: Int = 3628800

scala> z { (f:List[Int]=>List[Int]) => (xs:List[Int]) => xs match {
     |   case Nil => Nil
     |   case x :: xs =>
     |     val (l,r) = xs partition (_ <= x)
     |     f(l) ::: (x :: f(r))
     | }} { List(3,4,6,7,6,543,466,433,75,231,544,212,3,4,3) }
res3: List[Int] = List(3, 3, 3, 4, 4, 6, 6, 7, 75, 212, 231, 433, 466, 543, 544)

qsort はよく filter 使うけど、partition なんてのもあるのか。

  • 論理値を関数っぽく
scala> implicit def boolToProc(b: Boolean) = {
     |   def if_(t: => Unit)(f: => Unit) = if (b) t else f
     |   if_ _
     | }
boolToProc: (Boolean)(=> Unit) => (=> Unit) => Unit

scala> (2 < 3) { println("hoge") } { println("piyo") }
hoge

scala> (4 < 3) { println("hoge") } { println("piyo") }
piyo

本当は、値返せるようにしたかったけど、

scala> implicit def boolToFunc[A](b: Boolean): (=> A) => (=> A) => A = {
     |   def k[A1,A2](x: => A1)(y: => A2) = x
     |   def f[A1,A2](x: => A1)(y: => A2) = y
     |   if (b) k _ else f _
     | }
boolToFunc: [A](b: Boolean)(=> A) => (=> A) => A

scala> (2 < 3) { 23 } { 34 }
<console>:7: error: type mismatch;
 found   : Int(23)
 required: A
       (2 < 3) { 23 } { 34 }

んー・・・・・・

  • 追記

id:jmtaro さんがScala で論理値を関数っぽく、の勝手に続きでやってくれました。
なるほど、apply という手がありましたか。その辺の存在をすっかり忘れていた・・・

scala> implicit def boolToFunc(b: Boolean) = new {
     |   def apply[A](x: => A)(y: => A) = if (b) x else y
     | }
boolToFunc: (Boolean)java.lang.Object{def apply[A](=> A)(=> A): A}

scala> (2 < 3){ 23 }{ 34 }
res0: Int = 23

scala> (4 < 3){ 23 }{ 34 }
res1: Int = 34

ほほーう。