1

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?

4
  • I can not compile your code. Commented Nov 9, 2015 at 12:03
  • As it stands, this does not compile for me (and I would not expect it to - the type Pair / Tuple2 doesn't have a map method). Is there a List or Map involved here that you have tried to take out to simplify the question? Commented Nov 9, 2015 at 12:03
  • Apparently shapeless does support Tuple#map Commented Nov 9, 2015 at 12:07
  • @rahilb it was added at 2.0 version as mentioned in Miles's answer Commented Nov 9, 2015 at 15:15

2 Answers 2

7

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,"")
Sign up to request clarification or add additional context in comments.

2 Comments

it seems i got 'map' from scalaz imported, which is probably misled me)
@stanislav.chetvertkov map in scalaz treats Tuple2 as monad. During map it will change only second part as defined here
0

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,)

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.