Reputation: 1640
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
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
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