Why is Some (1) .getOrElse (Some (1)) not of type Option [Int]?

I am currently working on a project with Scala, and it seems that I do not quite understand the Scala System: - /

I have the following situation:

def reviews(id: Int) = Action { implicit request => Ok(html.products.reviews( reviewlist, reviewlist .find(review => review.id == id) .getOrElse(reviewlist.headOption) )) } 

Unfortunately, the compiler says that it cannot convert Product to Option [Review], so I changed the code

 reviewlist .find(review => review.id == id) .getOrElse(reviewlist.headOption) 

with

 id match { case 0 => reviewlist.headOption case id => reviewlist.find(review => review.id == id) } 

which seems to be working now, although its not quite the same as it is, for example, no longer showing the first record if an invalid validation ID is sent. he will pretend that there are no reviews yet.

Then I broke the problem down to a simple veeery sample:

 val a: Option[Int] = Some(1).getOrElse(Some(1)) 

So, does anyone have an idea why the expression on the right side is not of type Option [Int]? Both, Some (1) and None inherit directly from Option, and is this expression actually Some (1) in either or am I mistaken?

Interesting enough

 val a: Option[Int] = None.getOrElse(None) 

works, but all other combinations do not ...

+6
source share
3 answers

You wanted:

 val a: Option[Int] = Some(1).orElse(Some(1)) 

Because the

 x.getOrElse(y) 

will return 1 if x is Some(1) or y (which is Some(1) ) if x is None , or says in code:

 if (Some(1).isDefined) 1 else Some(1) 
+13
source

A typical signature of Option.getOrElse is

 getOrElse[B >: A](default: ⇒ B): B 

This means that when you call getOrElse on Option[A] , it will try to return something like A . If the default type ( B ) does not match A , it will look for the closest common ancestor of A and B In your case, A and B are Option[Int] and Int . The best thing the compiler can do is Any .

+6
source

The parameter value has two representations, a good value ( Some(...) ) or a bad value ( None ).

With getOrElse you can reduce the parameter to the type contained in it. Imagine this is the process of unpacking a value by removing it from the container.

In this unpacking process, Option is deleted, and only the type that is contained in it is returned, so in your example, you really have this:

 val a int = Some(1).getOrElse(2) // 1 

And do what you need to do:

 val b Option[Int] = Some(1).orElse(Some(2)) // Some(1) 
+1
source

Source: https://habr.com/ru/post/949048/


All Articles