Можете ли вы указать аргумент типа для None или сказать компилятору, что это опция [String]?

Интересно, могу ли я написать что-то вроде этого в моем коде:

None[String]

Ответ 1

Я удивлен, что никто не упоминал о существовании Option.empty:

scala> Option.empty[String]
res0: Option[String] = None

Обратите внимание, что во многих случаях просто использовать None, где ожидается Option[String], будет работать нормально. Или, другими словами, (как показывает Алексей Измайлов), следующее верно:

def f(o: Option[String]) = ...; f(None)

Это связано с тем, что None расширяет Option[Nothing], поэтому в силу Option, являющегося ковариантным (и Nothing является подтипом любого другого типа), None всегда совместим с Option[T] для любого T.

Это также объясняет, что тип ascription также является прекрасной альтернативой (для случаев, когда вам нужно быть явным в типе опций, например, если это необходимо для ввода вывода типа):

scala> None: Option[String]
res0: Option[String] = None

Ответ 2

Option является параметризованным типом и определяется как таковой:

... sealed abstract class Option[+A] ...

он распространяется на 2 других класса:

final case class Some[+A](x: A) extends Option[A]

и

case object None extends Option[Nothing]

В то время как Some может принимать любой тип аргумента, None - специальный экземпляр/синглтон Option, параметризованный с помощью Nothing. Более того, Option является ковариантным в своем аргументе типа [+A], что означает, что Option[Nothing] можно использовать везде, где Option с любым другим типом аргумента ожидается, так как Nothing расширяет все типы в Scala. Поэтому нет необходимости создавать какие-либо другие значения для представления значения Nothing, для всех случаев будет достаточно одного элемента None.

В терминах расширяемости Option является закрытым абстрактным классом, поэтому вы не можете его расширять. Вы не можете расширять свои подклассы Some и None, так как они являются классами case.

Обычно вам даже не нужно пытаться написать что-то вроде None[String], потому что более конкретный тип Option определен где-то в контексте. Например, в качестве аргумента функции:

def f(o: Option[String]) = ...; f(None)

или как уточнение:

val o: Option[String] = None

Кроме того, вам действительно все равно, какой тип был опцией, если это значение Nothing, вы все равно ничего не получите от него, это как null в Java, но с монадическим поведением.

Было упомянуто, что вы можете сделать что-то подобное в scalaz: None[String]. Это просто синтаксический сахар, хотя и очень удобный, чтобы уменьшить многословие в некоторых случаях, когда типы должны быть аннотированы. Он определяется как таковой:

final def none[A]: Option[A] = None

Ответ 3

Если вы хотите указать тип Option, вы можете использовать:

Нет: Опция [Строка]

Двойник - это явная аннотация типа.

Ответ 4

Вы можете со сказазом:

import scalaz._
import Scalaz._

none[String]  // res0: Option[String] = None