Когда scala частичная функция не является частичной функцией?

При создании карты Строки к частичным функциям я столкнулся с неожиданным поведением. Когда я создаю частичную функцию как элемент карты, это хорошо работает. Когда я выделяю val, он вызывает вместо этого. Попытка вызвать проверку генерирует ошибку. Это ожидается? Я делаю что-то немое? Прокомментируйте 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 
}
8
задан duplode 5 November 2016 в 22:10
поделиться

2 ответа

Для удобства Scala позволяет вам опускать пустые скобки при вызове метода, но он достаточно умен, чтобы видеть, что ожидаемый тип в первом случае - () => Unit , поэтому он не удаляет все скобки за вас; вместо этого он преобразует метод в функцию для вас.

Однако в случае val check это выглядит как результат вызова функции, присвоенный переменной. Фактически, все три из них делают одно и то же:

val check = dream
val check = dream()
val check = dream()()

Если вы хотите превратить метод в функцию, вы помещаете _ после метода вместо списка аргументов (s ) . Таким образом,

val check = dream() _

будет делать то, что вы хотите.

12
ответ дан 5 December 2019 в 10:01
поделиться

Проблема в том, что вы все неправильно поняли. : -)

Вот некоторые концептуальные ошибки:

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 выполняет преобразование, потому что средство вывода типов может угадать правильный тип.

val check = dream()         // unexpected invocation

Здесь нет ожидаемого типа, который мог бы помочь механизму вывода типов.Однако пустые списки параметров можно опустить, так что это просто вызов метода.

5
ответ дан 5 December 2019 в 10:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: