Подтвердить что ты не робот

В чем разница между() => Int и Unit => Int? Какой тип "()" в Scala?

Я думаю, что я до сих пор не совсем понял, что тип() представляет во время определения функции. Поэтому я не могу привести конкретный пример каждого случая:() = > Int; Unit = > Int.

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

Спасибо

* EDIT: * destin говорит, что они такие же. Но следующий тест, по-видимому, указывает иначе:() нельзя использовать в ожидании Unit.

scala> def inCase[A] ( b :Boolean, ifTrue : Unit => A, ifFalse : Unit => A ) : A  = 
 |     b match {
 |         case True => ifTrue()
 |         case _ => ifFalse()
 |     }

 inCase: [A](b: Boolean, ifTrue: Unit => A, ifFalse: Unit => A)A


scala> inCase( True,  () => 1,  () => -1 )
 <console>:11: error: type mismatch;
 found   : () => Int
  required: Unit => ?
          inCase( True,  () => 1,  () => -1 )
4b9b3361

Ответ 1

() в типе функции вообще не является типом, и это не значение. () => - просто синтаксис, указывающий на функцию, которая принимает нулевые аргументы. См. Нотацию BNF в разделе 3.2.9 спецификацию Scala.

Когда вы видите (Type1, Type2, Type3) => Type4, () окружает все типы аргументов, которые выполняет функция. (Type1, Type2, Type3) здесь не является кортежем - скобки являются просто синтаксисом. Поэтому, когда вы видите () => Type4, у вас есть список аргументов, который принимает нулевые параметры. Отдельные функции аргументов являются особенными, поскольку вы можете опустить круглые скобки.

Функции без аргументов, заданные без (), просто => Type4 являются параметрами по-имени (которые выглядят как значения, но реализуются как функции, которые вызываются неявно, когда вы пытаетесь оценить их значение.) Они - re, определенном в разделе 4.6.1 спецификации.

Скобки могут означать кучу других вещей в других контекстах.

  • Скобки в объявлении типа функции в любом месте, кроме правого перед =>, указывают тип кортежа, и они не могут быть пустыми. (Раздел 3.2.5)
  • Пустые круглые скобки () - это возвращаемое значение функций, тип возврата которых Unit. (Раздел 12.2.3) Это фактически становится реальным значением в определенных контекстах, например println(println("foo")) будет печатать

    foo                 <--- the argument to the inner println
    ()                  <--- the argument to the outer println
    
  • Круглые скобки также являются синтаксисом для аргументов функции при вызове функции, о чем вы, вероятно, уже знаете. Они могут быть пустыми. Они определены в разделе 6.6 спецификации.

  • Круглые скобки также являются синтаксисом аргументов функции при определении метода с использованием def. Они описаны в разделе 4.6 спецификации.
  • Круглые скобки также являются синтаксисом для создания значений кортежа (раздел 6.9). Если они не пусты, вы получите TupleN, где N - количество значений внутри круглых скобок. Если они пусты, тип этого выражения равен Unit. (Разделы 6.9, 12.2.3)

Ответ 2

Я изменил ваш пример, чтобы иметь обе записи (и использовать более популярные логические):

def inCase[A] (b:Boolean, ifTrue: ()=> A, ifFalse: Unit => A): A = b match {
  case true => ifTrue ()
  case _    => ifFalse ()
}

inCase (true, () => 1,  (Unit) => -1)

Затем я должен использовать те же обозначения на вызывающем сайте.

Ответ 3

() является единственным экземпляром типа Unit.
So () => Int как подпись частичной функции означает: берет объект Unit, делает что-то и дает Int.
Unit => Int означает: принимает любой объект Unit, делает что-то и дает Int.

Edit

"Scala s Тип элемента грубо соответствует void в Java, он используется всякий раз, когда функция не возвращает интересный результат. Фактически, поскольку Scala является языком с выражением, каждая функция возвращает некоторый результат. дается явное выражение return, предполагается значение(), которое произносится как" единица". типа. Функции возврата единиц также называются процедурами. Heres больше "выражение-ориентированная" формулировка функции подкачки в первой реализации quicksort, что делает это явным:

def swap(i: Int, j: Int): Unit = {
  val t = xs(i); xs(i) = xs(j); xs(j) = t
  ()
}

Значение результата этой функции - просто ее последнее выражение - ключевое слово return не обязательно. Обратите внимание, что для функций, возвращающих явное значение, всегда требуется "=" перед их телом или определением выражения. "

Источник: Программирование в Scala - Мартин Одерский (стр. 14)