2015-12-16 3 views
1

Странно, но мой код печатает u. Любые идеи, почему он делает такие вещи?Scala: PartialFunction странное поведение

object PF extends App { 
    val f1: PartialFunction[Int, String] = { 
    case x: Int if x % 2 == 0 => "2" 
    } 

    val f2: PartialFunction[Int, String] = { 
    case x: Int if x % 3 == 0 => "3" 
    } 

    val f3: PartialFunction[Int, String] = { 
    case x: Int if x % 5 == 0 => "5" 
    } 

    val result = f1.orElse(f2.orElse(f3.orElse("<undef>"))) 
    println(result.apply(1))  
} 

ответ

2

Ваш код интерпретирует строку "", как PartialFunction:

val result: PartialFunction[Int, String] = "<undef>" 
result.apply(1) // second character of "<undef>" --> u 

Это происходит за счет неявного преобразования из String в WrappedString, который является подтипом Seq[Char]. Кроме того, Seq[T] является подтипом PartialFunction[Int, T] (с учетом индекса, получить элемент Seq, если он существует).

Последняя линия достигает этого случая, так как 1 не делится ни на один из 2,3,5 (поэтому он падает через f1, f2 и f3).

То, что вы хотели бы вместо этого applyOrElse:

val fun = f1 orElse f2 orElse f3 
fun.applyOrElse(1, "<undef>") // --> "<undef>" 

В качестве альтернативы, вы можете указать частичную функцию резервного:

val result = f1 orElse f2 orElse f3 orElse { 
    case _ => "<undef>" 
} 
+0

Да, я вижу. Но почему компилятор позволяет подставлять типы (PartialFunction -> String)? Я предполагаю, что существует некоторое неявное преобразование, которое заменяет PF на String. Но я не могу его найти. – Finkelson

+0

Я обновил свой ответ с объяснением. Надеюсь, это понятно :) – gzm0

Смежные вопросы