PartialFunction
specs2のAnyMatchers#beLike
を使ってみようと思ったらPartialFunction
なるものがでてきたので調べた
/** matches if the value returns a successful result when applied to a PartialFunction */ def beLike[T](pattern: PartialFunction[T, MatchResult[_]]) = new Matcher[T] {
PartialFuction(部分関数)ってなに?
まずDocs
概要
引数をひとつ取り、その引数が特定の値のときのみ結果を返却する関数
内部をみてみる
trait PartialFunction[-A, +B] extends (A => B) { self =>
まずFunction1
を継承しているのがわかる
Function1
は引数を1つとるごく普通の関数でたとえば
// こんなやつね def hoge(arg: Int): Int = arg + 1
簡単な例をみながら
val hoge = new PartialFunction[String, String] { def isDefinedAt(in: String): Boolean = in match { case "hoge" => true case _ => false } def apply(in: String): String = in match { case "hoge" => "hoge1" } }
PartialFunction[-A, +B] extends (A => B)
に対してPartialFunction[String, String]
なのでこれは、
String
を受け取り、String
を返すFunction1
を継承しているisDefinedAt
っていうのが、引数が有効かどうか判定する関数でこいつがture
返すものだけに結果を返却しfalse
の場合はMatchError
をはくようになっている。
実践
"hoge"が渡されれば、"hoge1"が返却され
val hoge_1 = hoge("hoge") hoge: PartialFunction[String,String] = <function1> hoge_1: String = hoge1
"hogehoge"が渡されればMatchError
が返る
val hoge_2 = hoge("hogehoge") scala.MatchError: hogehoge (of class java.lang.String) at $anon$1.apply(<console>:16) at $anon$1.apply(<console>:11) ... 36 elided
ひとまずParcialFunctionの概要はこんなかんじ
おまけ
syntaxsugar
{ case ... }
がPartialFunctionのリテラルにないて簡単にかくことができる
scala> :paste // Entering paste mode (ctrl-D to finish) val hoge: PartialFunction[String, Int] = {case "1" => 1} // Exiting paste mode, now interpreting. hoge: PartialFunction[String,Int] = <function1>
ただ、型推論が聞かないらしく型の明示は必要っぽいね
scala> val hoge = {case "1" => 1} <console>:11: error: missing parameter type for expanded function The argument types of an anonymous function must be fully known. (SLS 8.5) Expected type was: ? val hoge = {case "1" => 1} ^ scala> val hoge: PartialFunction[String, Int] = {case "1" => 1} hoge: PartialFunction[String,Int] = <function1>