2

In Scala, how can I append an Option[A] to Option[A]:

Meaning:

Some("foo") ??? Some("bar") == Some("foobar")

In Haskell I'd use an applicative:

ghci>import Control.Applicative
ghci> (++) <$> (Just "foo") <*> (Just "bar")
Just "foobar"

Are there Applicatives in Scala's standard Typesafe library?

Kevin Meredith
  • 41,036
  • 63
  • 209
  • 384
  • 1
    Note that in this specific case if you're using Scalaz the semigroup instance for `Option[A: Semigroup]` is a little clearer—you just write `a |+| b`. – Travis Brown Sep 19 '14 at 14:23

3 Answers3

3

With scalaz you can do it this way:

  import scalaz.syntax.applicative._
  import scalaz.std.option._

  val l: Option[String] = Some("foo")
  val r: Option[String] = Some("bar")
  val result = ^(l, r)(_ + _)
  println(result) // Some("foobar")
Eugene Zhulenev
  • 9,714
  • 2
  • 30
  • 40
2

Applicatives aren't in the standard library, but you can use for-comprehensions like monads in Haskell:

for {
  l <- Some("foo")
  r <- Some("bar")
} yield (l + r)

(or rewrite it with flatMap, of course). Otherwise, go with scalaz, as in Eugene's answer.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
0

If you just want to achieve this particular syntax, you can combine an implicit class with a monad for-comprehension:

implicit class RichOption(a: Option[String]) {
  def ???(b: Option[String]) = for (sa <- a; sb <- b) yield sa+sb
}

scala> Some("foo") ??? Some("bar") == Some("foobar")
res4: Boolean = true
bluenote10
  • 23,414
  • 14
  • 122
  • 178