I'd like to try Monocle library. But i could not find help resources for base syntax.
In short i need optics Map[K,V] -> A having optics V -> A, how could i define this?
Suppose i have some
import monocle.macros.GenLens
case class DirState(opened: Boolean)
object DirState {
val opened = GenLens[DirState](_.opened)
}
type Path = List[String]
type StateStore = Map[Path, DirState]
Next I encounter place where i need simple StateStore => StateStore, so I'm importing
import monocle._
import monocle.std._
import monocle.syntax._
import monocle.function._
And trying to define first:
def setOpened(path: Path): StateStore => StateStore =
at(path) composeLens DirState.opened set true
Getting here
ambiguous implicit values: both method
atMapintrait MapInstancesof type[K, V]=> monocle.function.At[Map[K,V],K,V]and methodatSetintrait SetInstancesof type[A]=> monocle.function.At[Set[A],A,Unit]match expected typemonocle.function.At[S,Path,A]
Trying to change my definition to
def setOpened(path: Path): StateStore => StateStore =
index(path) composeLens DirState.opened set true
Getting now:
type mismatch; found :
monocle.function.Index[Map[Path,Nothing],Path,Nothing](which expands to)monocle.function.Index[Map[List[String],Nothing],List[String],Nothing]required:monocle.function.Index[Map[Path,Nothing],Path,A](which expands to)monocle.function.Index[Map[List[String],Nothing],List[String],A]Note:
Nothing <: A, buttrait Indexis invariant in typeA. You may wish to defineAas+Ainstead. (SLS 4.5)
import monocle.function.index._
import monocle.std.map._
import monocle.syntax._
def setOpened(path: Path)(s: StateStore): StateStore =
(s applyOptional index(path) composeLens DirState.opened).set(true)
let's have a look at the type of index
def index[S, I, A](i: I)(implicit ev: Index[S, I, A]): Optional[S, A] =
ev.index(i)
trait Index[S, I, A] {
def index(i: I): Optional[S, A]
}
So index summon an instance of type class Index of type Index[S, I, A].
This permits to use index for Map, List, Vector and so on.
The problem is that scala compiler needs to infer 3 types: S, I and A at the call site of index. I is easy, it is the type of the parameter you pass to index. However,S and A are only know when you call set.
The apply syntax has been created to guide type inference for such scenario, basically applyOptionalcaptures S which is Map[Path, DirState]. This gives enough information for the compiler to infer A =:= DirState.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With