Simple problem, where is the (probably) obvious error?

Hi all,

I have a hobbyist background in C++ and Python, but I’ve started higher education again and I am required to learn Scala.

I have:
case class Carte(c: Couleur, v: Valeur) (Carte = Card in French)
I am supposed to test whether two cards have the same color.
I wrote:
def couleurCommune(c1: Carte, c2: Carte): Option[Couleur] = {
if (c1.c == c2.c) c1.c
but it is not accepted by the compiler. Even the if (c1.c == c2.c) part seems to be wrong. Message is:
type mismatch; found : Unit required: Option[fr.istic.si2.tp2.cartes.Couleur]

Thanks for your help.

One way to solve it is to add “else None”. The reason why it doesn’t compile is that the code it’s returning the colour only when the two cards have the same colour, thus not covering the case when they have different colours. Scala follows the substitution principle: since the body of the function is does not correspond to the type Option[Colour] because you’re not handling one of he cases, it infers the type Unit and therefore the error.

Thanks a lot.
Actually to make it work I had to also add an Option casting (?) in front of c1.c
if (c1.c == c2.c) Option(c1.c) else None
which puzzles me a little but I guess that with time I will understand better.

Thanks again.

You required the function return “…): Option[Couleur]”. The compiler is
trying to.let you know that the outcome of the function is not, it’s a
Unit. Make the last thing in the function create a Option[Couleur] and that
problem will go away.

In fact, in my assignment, I have skeleton functions that I shall complete so I sometimes don’t entirely grasp what is required.

In Scala Option[A] is just a normal class. It can either contain one value of type A or nothing. You can construct an instance of Option[String] with Some("foo") if you have the value "foo" or None if you have no value. Alternatively you can construct an Option with Option(bar) which will return a None if bar == null.

Hello lanig.

Just to complete comments, Scala’s Option[Type] is very idiomatic and it’s everywhere. You’ll get used to it very soon.

Taking your example, It is declared with Option[Boolean]. It is used with Some(true) or Some(false).

The usual case when you might find it useful is to report a value or the absense of it.

A good example is querying a Hash (Map) whether a value is present or not:

groupOfCards.get (certainCard) match {
    case Some (card) => /* do something with with card */
    case None => /* no card was found */

In your particular case, it is not interesting to use Option[Boolean] because you know that the color will match or not, but in any case you will have a value (Boolean). true or false.

In essense, there’s no absence, so Option[Boolean] helps nothing here.

Putting in practise this, a valid, though not optimal way of implementing your example will be (let me reword your example to english for more people to understand):

// working example, but not recommended
def sameColour (c1 : Card, c2 : Card) : Option[Boolean] = Some (c1.c == c2.c)

Why it is not recommended? As we have said, it is not recommended because you always have a value, so returning always Some(true) or Some(false) will only add burden to the API consumer, plus, you can resolve the problem directly:

// working recommend example
def sameColour (c1 : Card, c2 : Card) : Boolean = {
   c1.c == c2.c

…and, even shorter, using Scala type system:

// let Scala infer types
def sameColour (c1 : Card, c2 : Card) = c1.c == c2.c

Thanks for your detailed explanations. Scala is really different from the languages I have learned before.

Looking at the initial post, the return type for sameColour was Option[Color], and not Option[Boolean].
Option[Boolean] would be weird, I agree.
The def is supposed to return the common color of the two cards, whenever it exists.