optional - Scala Option type upper bound don't understand -


i'm reading functional programming in scala, , in chapter 04 authors implement option on own. now, when defining function getorelse use upper bound restrict type of a supertype (if understood correctly)

so, definition goes:

sealed trait option[+a] {    def getorelse[b >: a](default: => b): b = match {      case none => default      case some(a) =>    } } 

so, when have

val = some(4) println(a.getorelse(none)) => println prints integer value val b = none println(b.getorelse(some(3)) => println prints option[integer] value 

a has type option[int], a type int. b type nothing. nothing subtype of every other type. means option[nothing] subtype of option[int] (because of covariance), right?

but b >: a said b has supertype?! how can int back? bit confusing me...

anyone care try , clarify?

that means option[nothing] subtype of option[int] (because of covariance), right?

correct. option[nothing] option[int].

but b >: said b has supertype?! how can int back?

it doesn't have super-type. requires a lower-bound. means can still pass int getorelse if a int.

but doesn't mean can't pass instances of sub-class. instance:

class class b extends class c extends b  scala> option(new b) res196: option[b] = some(b@661f82ac)  scala> res196.getorelse(new c) res197: b = b@661f82ac  scala> res196.getorelse(new a) res198: = b@661f82ac  scala> res196.getorelse("...") res199: object = b@661f82ac 

i can still pass instance of c, because c can up-cast b. can pass type higher inheritance tree, , getorelse return type, instead. if pass type has nothing type contained in option, type least upper-bound inferred. in above case, it's any.


so why lower-bound there @ all? why not have:

def getorelse[b <: a](default: => b): b 

this won't work because getorelse must either return a that's contained in option, or default b. if return a, , a not b, type-bound invalid. perhaps if getorelse returned a:

def getorelse[b <: a](default: => b): 

this work (if defined way), restricted type-bounds. in above example, pass b or c getorelse on option[b]. in case, not how in standard library.


the standard library getorelse allows pass it. have option[a]. if pass sub-type of a, up-cast a. if pass a, okay. , if pass other type, compiler infers least upper-bound between two. in cases, type-bound b >: a met.

because getorelse allows pass it, many consider tricky. example have:

val number = "blah" // ... lots of code val result = option(1).getorelse(number) 

and compile. we'll have option[any] cause error somewhere else down line.