3

In Functional Programming in Scala chapter 4 we are provided the following definitions for map, getOrElse and flatMap for the Option type:

def map[B](f: A => B): Option[B] = this match {
  case Some(x) => Some(f(x))
  case _ => None
}

def getOrElse[B>:A](default: => B): B = this match {
  case Some(x) => x
  case _ => default
}

def flatMap[B](f: A => Option[B]): Option[B] = 
  map(f) getOrElse None

I get what flatMap is doing, but I don't get how the call map(f) in flatMap's definition works. f has A => Option[B] as its type in flatMap, yet we seem to be able to call map, which expects a function of type A => B, with f. The call getOrElse None is obviously the key, but I don't understand how it allows us to call map(f) in flatMap.

2 Answers 2

4

When you call flatMap and pass the function A => Option[B], flatMap calls map and passes the same function, but the B in flatMap is not same B as in map. For example, if you pass some

Int => Option[String]

Then for map, B = Option[String] and will return Option[Option[String]].

Thus the getOrElse in flatMap to get the will either retrieve the inner Option[B] or return None.

Sign up to request clarification or add additional context in comments.

4 Comments

Makes sense... but why do I get the following error when I comment out the call to getOrElse ------------------------------------------- type mismatch; [error] found : A => fpinscala.errorhandling.Option[B] [error] required: A => B [error] map(f) //getOrElse None ---------------------------------------- It seems like the call to map is failing
If you remove the getOrElse then you have Option[Option[B]] instead of Option[B]
Yes I get that - but why should the call to map fail just because I comment that out. I know the call to getOrElse is essential for flatMap do to its "flattening", but why should the call to map care. It seems like from the error message that map is saying "you cant call me with a function with the type A=>Option[B], I require: A=> B. Am I interpreting the compiler error wrong?
its not that the call to map fails, it's that the result of that expression is not the type that you said would be the result of the entire function. if you were to change it to "val x = map(f); true" it would no longer be complaining about what is going on with map, but it would say that "true" is not an Option[B], its just looking for the last expression in the block to be of type Option[B], in this case, if map(f) is going to result in an Option[B] then f must be a A=>B not an A=>Option[B]
3

B is just a name for the variable type parameter. It only has meaning within its scope. In other words B in map and flatMap definitions do not have to be the same, they are completely different parameters.

The could have written absolutely equivalently:

def flatMap[C](f: A => Option[C]): Option[C] = 
  map(f) getOrElse None

Now, in this terms, it is easy to see, that map used here has Option[C] as the value for its type parameter.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.