Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assign to Option only if it is None

Tags:

ruby

scala

In ruby it is possible to do it like so:

first ||= number

and first will get the value of number only if it is nil

How to do similar thing in scala?

So far I've come up with this and it doesn't look as nice as in ruby.

var first: Option[Int] = None
...
first = if (first == None) Option(number) else first
// or
first = Some(first.getOrElse(number))
like image 660
Anton Kuzmin Avatar asked Dec 19 '22 19:12

Anton Kuzmin


1 Answers

There is a scalaz operator for this:

import scalaz._, Scalaz._

none[Int] <+> 1.some
// Some(1)

2.some <+> 1.some
// Some(2)

You could use a <+>= b instead of a = a <+> b:

var i = none[Int] // i == None
i <+>= 1.some // i == Some(1)
i <+>= 2.some // i == Some(1)

See also Plus[F[_]] in scalaz cheatsheet.

For Option plus is implemented as orElse.

For collections (List, Vector, Stream, etc) Plus is implemented as append:

Vector(1, 2) <+> Vector(3, 4)
// Vector(1, 2, 3, 4)

I can't find a method to combine Option[T] and T in the way you want, but you could write such method like this:

implicit class PlusT[T, M[_]: Plus : Applicative](m: M[T]) {
  def ?+?(t: T) = m <+> t.point[M]
}

none[Int] ?+? 1
// Some(1)

2.some ?+? 1
// Some(2)

var i = none[Int] // i == None
i ?+?= 1 // i == Some(1)
i ?+?= 2 // i == Some(1)

You could rename this method to || and use it like ||= just like in Ruby, but this name can confuse other developers - there is already method || for Boolean.

like image 138
senia Avatar answered Jan 02 '23 15:01

senia