softshipper
softshipper

Reputation: 34099

Expression of type Right[Nothing, Map[String, String]] doesn't conform to expected type Left[String, Nothing]

I have the following code, that does not compile:

object PcpProtocol {

  private type PcpKV = String

  private val findPublicKey: List[PcpKV] => Either[String, Map[String, String]] = kv =>
    kv
      .filter(_.contains("PUBLIC:"))
      .foldLeft(Left("Can not find the public key from SAP.")) { (_, a) =>
        a.split(":").toList match {
          case List(key, value) => Right(Map(key -> value))
        }

      }
} 

The compiler complains:

type mismatch;
[error]  found   : scala.util.Right[Nothing,scala.collection.immutable.Map[String,String]]
[error]  required: scala.util.Left[String,Nothing]
[error]           case List(key, value) => Right(Map(key -> value))  

What am I doing wrong?

Upvotes: 2

Views: 744

Answers (2)

Krzysztof Atłasik
Krzysztof Atłasik

Reputation: 22625

The compiler can't infer type Either[String, Map[String, String]] correctly because it narrows it to Left[String].

You can add type explicitily:

.foldLeft(Left("Can not find the public key from SAP."): Either[String, Map[String, String]]) { (_, a) =>

or:

.foldLeft[Either[String, Map[String, String]]](Left("Can not find the public key from SAP.")) { (_, a) =>

If you use cats in your project you could also use:

"Can not find the public key from SAP.".asLeft[Map[String, String]]

It often a good idea to create type alias for either, like:

type ErrorOr[T] = Either[String, T]

which could give you a little bit more readability:

.foldLeft[ErrorOr[Map[String, String]]]

Upvotes: 4

talex
talex

Reputation: 20534

You can help compiler by specifying type explicitly.

  private val findPublicKey: List[PcpKV] => Either[String, Map[String, String]] = kv =>
    kv
      .filter(_.contains("PUBLIC:"))
      .foldLeft[Either[String, Map[String, String]]](Left("Can not find the public key from SAP.")) { (_, a) =>
        a.split(":").toList match {
           case List(key, value) => Right(Map(key -> value))
        }
    }

Upvotes: 4

Related Questions