stanislav.chetvertkov
stanislav.chetvertkov

Reputation: 1640

Map tuple to tuple in Scala

I want to map a pair of options of String like the following

val pair: (Option[String], Option[String]) = (Some("a"), None)

val mapped: (String, String) = pair map {case (a:Option[String],b:Option[String]) => (a.getOrElse(""),b.getOrElse(""))}

but the output signature is different from what I expected

(Option[String],(String,String))

It seems that I'm missing something here... maybe scalaz or shapeless allows for such functionality of mapping tuples?

Upvotes: 1

Views: 1167

Answers (2)

Odomontois
Odomontois

Reputation: 16308

In case if you specifically want to do things like that with shapeless, you should make some preparations.

First tell your compiler what you want to use in case of None:

class Default[T](val value: T)

implicit object defaultString extends Default[String]("")

Now create your function to map:

import shapeless._

object extract extends Poly1 {
  implicit def withDefault[T](implicit default: Default[T]) =
    at[Option[T]](_ getOrElse default.value)
}

Now use shapeless extension for tuples:

import syntax.std.tuple._

pair.map(extract) // res0: (String, String) = (a,)

Upvotes: 0

vvg
vvg

Reputation: 6385

Simple change from map to match you'll get expected types.

scala>   val pair: (Option[String], Option[String]) = (Some("a"), None)
pair: (Option[String], Option[String]) = (Some(a),None)

scala>

scala>   val mapped: (String, String) = pair match {case (a:Option[String],b:Option[String]) => (a.getOrElse(""),b.getOrElse(""))}
mapped: (String, String) = (a,"")

scala>

scala>   mapped
res8: (String, String) = (a,"")

Upvotes: 7

Related Questions