Синтаксическая функция PartialFunction и Function1 - PullRequest
3 голосов
/ 17 марта 2019

В рамках моего путешествия, изучая Scala, а затем Akka, я пытаюсь понять, как можно определить PartialFunction.

. В курсе "Программирование реактивных систем" приведен примерАктер:

class Toggle extends Actor {
  def happy: Receive = {
    case "How are you?" =>
      sender ! "happy"
      context become sad
  }
  def sad: Receive = {
    case "How are you?" =>
      sender ! "sad"
      context become happy
  }
  def receive = happy
}

Это довольно просто, и я бы сказал, я понимаю, что он пытается сделать.То, что я не понимаю, это то, что happy и sad имеют тип Function1 (или, по крайней мере, это мое убеждение), и все же они могут играть роль PartialFunction (receive нуждается в PartialFunction).

И, что еще хуже, согласно документации Akka , receive должен возвращать PartialFunction (не одно):

abstract def receive: Actor.Receive

Scala API: это определяет начальное поведение актера, оно должно возвращать частичную функцию с логикой актера.

Но насколько ямогу сказать, happy и sad не возвращают PartialFunction, они едины.

Чтобы подвести итог моих вопросов:

  1. Есть ли способ определитьPartialFunction против Function1?
  2. Я неправильно прочитал пример?Разве receive a PartialFunction не возвращает Unit?Если ответ «да», то почему в документации сказано, что receive должен возвращать PartialFunction?

[ОБНОВЛЕНИЕ]

На основании ответаЯ получил от @Brian McCutchon, теперь я знаю, что метод receive должен возвращать PartialFunction.Но это не поможет с моей путаницей вообще!Рассмотрим следующий сценарий:

def someFunction(): Receive = {
  //Instantiates and returns a Receive object
}

class Toggle {
  def happy: Receive = {
    case "How are you?" =>
      someFunction()
  }
}

Мой вопрос: как компилятор Scala узнает, должен ли данный код быть расширен до этого:

class Toggle {
  def happy: Receive = {
    return {
      case "How are you?" =>
        someFunction() // <-- The returned object of this function call is dismissed
    }
  }
}

Или это:

class Toggle {
  def happy: Receive = { // <-- Starting point of happy's body
    case "How are you?" =>
      someFunction() // <-- The Receive object is returned by this method
  }
}

Или, что более важно, откуда мне знать, какое расширение произойдет?И я думал, что современные языки программирования должны быть более читабельными !!!

1 Ответ

7 голосов
/ 17 марта 2019

happy и sad относятся к типу Function1

Нет, это методы, которые возвращают Receive, который является псевдонимом типа для PartialFunction[Any, Unit].Заданная вами аннотация типа показывает этот тип возврата.Частичные функции могут использовать тот же лямбда-синтаксис, что и Function1 (и другие типы SAM ), и в этом случае они различаются только контекстом (в данном случае, аннотацией вашего типа).

receive должен вернуть PartialFunction (не являющийся единицей)

Вы запутались в терминологии.receive - это метод, а не PartialFunction, как вы объявили его с def.Возвращает PartialFunction[Any, Unit] (он же Receive).Это также должно прояснить ваше замешательство по поводу happy и sad.

. Это разумный источник путаницы, поскольку синтаксис настолько лаконичен, что выглядит так: receive и PartialFunction itвозвраты это одно.Это может помочь понять, что ваш код может быть расширен до этого (хотя я бы не советовал это на практике):

class Toggle extends Actor {
  def happy: Receive = {
    return {
      case "How are you?" =>
        sender ! "happy"
        context become sad
    }
  }
  def sad: Receive = {
    return {
      case "How are you?" =>
        sender ! "sad"
        context become happy
    }
  }
  def receive = {
    return happy
  }
}

Согласно вашему обновлению, первое расширение является правильным.Второе не имеет смысла, поскольку тела методов не могут начинаться с case, что должно указывать на то, что вы имеете дело с лямбда-выражением.Подводя итог: если блок начинается с аргументов лямбда (например, x =>), или он начинается с case и не является блоком match, это лямбда.

...