jinglining
jinglining

Reputation: 329

Can you specify type argument for None or tell compiler that it's an Option[String]?

I wonder if I can write something like this in my code:

None[String]

Upvotes: 32

Views: 13846

Answers (4)

yǝsʞǝla
yǝsʞǝla

Reputation: 16422

Option is a parameterized type and is defined as such:

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

it's being extended by 2 other classes:

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

and

case object None extends Option[Nothing]

While Some can take any type of an argument, None is a special instance/singleton of an Option parameterized with Nothing. Furthermore Option is covariant in its type argument [+A] which means that Option[Nothing] can be used anywhere where Option with any other argument type is expected, since Nothing extends all types in Scala. So there is no need to create any other values to represent a Nothing value, a singleton None will be sufficient for all cases.

In terms of extensibility Option is a sealed abstract class, so you can't extend it. You can't extend its subclasses Some and None since they are case classes.

Usually you don't even need to try to write something like None[String] because more specific Option type is defined somewhere in the context. For example, as a function argument:

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

or as a refinement:

val o: Option[String] = None

Moreover, you really don't care what type an Option was if it's a Nothing value, you can't get anything out of it anyway, it's like a null in Java but with Monadic behavior.

It's been mentioned that you can do something similar in scalaz: none[String]. This is just a syntax sugar, albeit very convenient, to reduce verbosity in some cases where types have to be annotated. It's defined as such:

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

Upvotes: 8

Régis Jean-Gilles
Régis Jean-Gilles

Reputation: 32729

I am surprised that nobody mentioned the existence of Option.empty:

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

Note that in many cases simply using None where an Option[String] is expected will work fine. Or in other words, (as shown by Aleksey Izmailov), the following is corrrect:

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

This is because None extends Option[Nothing], so by virtue of Option being covariant (and Nothing being a sub-type of every other type), None is always a compatible with Option[T] for any T.

This is also why type ascription is also a fine alternative (for the cases where you do need to be explicit on the type of options, by example if it is needed to drive type inference):

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

Upvotes: 63

dhg
dhg

Reputation: 52691

You can with scalaz:

import scalaz._
import Scalaz._

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

Upvotes: 0

Tim Destan
Tim Destan

Reputation: 2028

If you want to specify the type of Option you could use:

None:Option[String]

The colon is an explicit type annotation.

Upvotes: 9

Related Questions