Found: A => Unit; Required: PartialFunction[A, ?]


#1

I am writing a script that uses a closeable email client to send an email; afterward I want to log the result and then close the client.

Await.ready(client.sendEmail(message) andThen {
    case Success(result) => log.info(result.toString)
    case Failure(e) => throw e
  } andThen (_ => client.close()), 60.seconds)

The type checker does not like this:

type mismatch;
[error]  found   : scala.util.Try[Result] => Unit
[error]  required: PartialFunction[scala.util.Try[Result],?]
[error]   } andThen (_ => client.close()), 60.seconds)

Those types look compatible to me. What’s happening here?


#2

PartialFunction <: Function1


#3

Isn’t that an LSP violation?

As a library author, if I am expecting a Function1[A, B] and instead I get a PartialFunction[A, B] then my higher-order function will not work as expected on whatever parts of the domain the partial function is missing. Function1 <: PartialFunction would not have this problem, so what gives?


#4

And on a more practical note: what would be the idiomatic way to do what I am trying to do, then?


#5
andThen { case _ => client.close} 

#6

Despite the name, you should not think of Function1 as something defined everywhere and PartialFunction as something not defined everywhere.

You should think of PartialFunction as a Function that knows where it is defined.


#7

Oh, cool!

To close the loop on this, here is the corrected version:

Await.ready(client.sendEmail(message) andThen {
    case Success(result) => log.info(result.toString)
    case Failure(e) => throw e
  } andThen {case _ => client.close()}, 60.seconds)

Thanks everyone for clarifying.