Когда это Scala Partial функция не частичная функция?
Вопрос
При создании карты строки к частичным функциям я столкнулся с неожиданным поведением. Когда я создаю частичную функцию в качестве элемента карты, он работает нормально. Когда я выделяю на валь, это вызывает вместо этого. Пытаясь вызвать чек генерирует ошибку. Это ожидается? Я делаю что-то глупое? Комментировать check()
чтобы увидеть вызов. Я использую Scala 2.7.7
def PartialFunctionProblem() = {
def dream()() = {
println("~Dream~");
new Exception().printStackTrace()
}
val map = scala.collection.mutable.HashMap[String,()=>Unit]()
map("dream") = dream() // partial function
map("dream")() // invokes as expected
val check = dream() // unexpected invocation
check() // error: check of type Unit does not take parameters
}
Решение
Для удобства SCALA позволяет вам опустить пустые пары при вызове метода, но это достаточно умно, чтобы увидеть, что ожидаемый тип в первом случае ()=>Unit
, так что он не удаляет всех друзей для вас; Вместо этого он преобразует метод в функцию для вас.
в val check
Случай, однако, он выглядит так же, как и результат вызова функции, присвоенный для переменной. На самом деле, все три из них делают то же самое:
val check = dream
val check = dream()
val check = dream()()
Если вы хотите превратить метод в функцию, вы размещаете _
После метода вместо списка аргументов (ы). Отказ Таким образом,
val check = dream() _
сделаю то, что вы хотите.
Другие советы
Ну, проблема в том, что у вас все это неправильно. :-)
Вот несколько концептуальных ошибок:
def dream()() = {
println("~Dream~");
new Exception().printStackTrace()
}
Это не частичная функция. Это карриный метод с двумя пустыми списками параметров, которые возвращаются Unit
.
val map = scala.collection.mutable.HashMap[String,()=>Unit]()
Тип значений в этой карте не является частичной функцией, а функция. Конкретно, Function0[Unit]
. Отказ Частичная функция будет иметь тип PartialFunction[T, R]
.
map("dream") = dream() // partial function
Что происходит вот что Scala преобразует частично прикладной способ в функцию. Это не простое задание. Scala делает преобразование, потому что тот тип Type может угадать правильный тип.
val check = dream() // unexpected invocation
Здесь нет ожидаемого типа, чтобы помочь The Type Inferencer. Однако пустые списки параметров могут быть уверены, поэтому это просто вызов метода.