39

What's the difference between Some and Option?

scala> Some(true)
res2: Some[Boolean] = Some(true)

scala> val x: Option[Boolean] = Some(true)
x: Option[Boolean] = Some(true)

scala> res2 == x
res3: Boolean = true

I see that Option(null) returns, whereas Some(null) won't compile:

scala> val x = Option(null)
x: Option[Null] = None

scala> val x: Option[Boolean] = Some(null)
<console>:7: error: an expression of type Null is ineligible for implicit conversion
       val x: Option[Boolean] = Some(null)
                                     ^
Kevin Meredith
  • 41,036
  • 63
  • 209
  • 384
  • 1
    possible duplicate of [Difference between Option(value) and Some(value)](http://stackoverflow.com/questions/22908662/difference-between-optionvalue-and-somevalue) – Noah Dec 23 '14 at 20:40
  • Not a dupe. But related to http://stackoverflow.com/q/27611133/1296806 Maybe a narrower title is needed. – som-snytt Dec 23 '14 at 20:50

4 Answers4

36

In short

           Option
            /   \
           /     \
          /       \
        Some     None

Option is container base which can be empty or full

While Some(x) represent full with 'x' being present in the container, None represents empty.

Ashish
  • 851
  • 12
  • 27
32

Well, Some extends Option, so it inherits everything except get and isEmpty (and some other methods implemented by a case class).

The companion object of Option has a special apply method for dealing with null:

def apply[A](x: A): Option[A] = if (x == null) None else Some(x)

But Some.apply is just the standard apply method generated for a case class.

Some(null) will compile in some circumstances, but it has type Some[Null] (or Option[Null]), which can only be assigned when the type argument of Option is a reference type.

scala> val a = Some(null)
a: Some[Null] = Some(null)

scala> val b: Option[String] = Some(null)
b: Option[String] = Some(null)

You're trying to assign a Some[Null] to an Option[Boolean], but a Null is not a sub-type of Boolean, because Boolean is a value type (primitive underneath) and cannot hold a value of null.

Michael Zajac
  • 55,144
  • 7
  • 113
  • 138
  • 1
    Yesterday's question about intersection of boxed primitives and null: http://stackoverflow.com/q/27611133/1296806 You might tell us why `null.asInstanceOf[Int]` is zero (by the spec) but the expected boxed type turns it into null instead of boxed zero. Alternatively, `Some(null) map (runtime.BoxesRunTime.unboxToInt)` is zero. – som-snytt Dec 23 '14 at 20:46
19

From the functional programming perspective, given an arbitrary type T, the type Option[T] is an algebraic datatype with data constructors None and Some(x:T).
This is merely a coded way of saying that, if the type T consists of values t1, t2, t3, ... then all the values of the type Option[T] are None, Some(t1), Some(t2), Some(t3), ...

Most everything else follows from this. E.g., if null is not a value of T, then Some(null) is not a value of Option[T]. This explains why

val x: Option[Boolean] = Some(null)

does not work, while

val x: Option[Null] = Some(null)

does.

Finally, specifically to Scala, there seems to be an additional quirk in that, "for convenience" one may say Option(null) when they mean None. I'd expect one can also say Option(t) when they mean Some(t).

4

The basic idea of Option is to eliminate using Null in order have a default value and avoid a NullPointerException. So Option can have Some value or None (replacing Null). Check out this great explanation of Option: Scala Option explained