quicklens icon indicating copy to clipboard operation
quicklens copied to clipboard

Setting nested Options to Some(value)

Open oripwk opened this issue 7 years ago • 6 comments

Hi,

Given a nested chain of Options, is there a way to coerce the most inner one to Some?

The current operator .each allows traversing Options, but acts like map:

import com.softwaremill.quicklens._

case class C(d: Option[Int])
case class B(c: Option[C])
case class A(b: Option[B])

val a = A(b = None)

a.modify(_.b.each.c.each.d.each).setTo(3)  //  res0: A = A(None)

(the result is A(None), but how can we achieve a A(Some(B(Some(C(Some(3))))))?)

It could be useful if there were some operator (say, all) which can act as follows:

a.modify(_.b.all.c.all.d.all).setTo(3) //  res0: A = A(Some(B(Some(C(Some(3))))))

oripwk avatar Oct 03 '17 07:10 oripwk

I'm afraid this is very option-chain-specific. Firstly, you wouldn't be able to use .modify, as there need not be a value. Secondly, if e.g. B had any other fields, there's nowhere to get their values from.

adamw avatar Oct 03 '17 16:10 adamw

What about a variation of at(idx: Int) which doesn't throw IndexOutOfBoundsException, and instead enlarges the sequence so accommodate the new index? Such a method could also be adapted to Options if we look at them as sequences if length 1.

oripwk avatar Oct 03 '17 17:10 oripwk

But what would you put in the indicies in between? Also, how would you initialize an "empty" object which would be added to the sequence?

adamw avatar Oct 03 '17 18:10 adamw

Maybe a type class Zeroable[A] with default implementations for all the primitives?

A completely alternative solution would be a withHead[A](a: A) which can work for all sequences (including Option, Either, etc.)

oripwk avatar Oct 03 '17 18:10 oripwk

Maybe Zeroable would work ... but I have the feeling that this takes the .each syntax a bit too far. Wouldn't, in such situations, just writing code in .setTo with the appropriate new instance creation logic be sufficient?

adamw avatar Oct 09 '17 15:10 adamw

Yeah, on a second thought, there's no much difference between .setTo and my suggestion.

I guess you're right :)

oripwk avatar Oct 11 '17 13:10 oripwk