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
atMap
intrait MapInstances
of type[K, V]=> monocle.function.At[Map[K,V],K,V]
and methodatSet
intrait SetInstances
of 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 Index
is invariant in typeA
. You may wish to defineA
as+A
instead. (SLS 4.5)
let's have a look at the type of
index
So
index
summon an instance of type classIndex
of typeIndex[S, I, A]
. This permits to useindex
forMap
,List
,Vector
and so on.The problem is that scala compiler needs to infer 3 types:
S
,I
andA
at the call site ofindex
.I
is easy, it is the type of the parameter you pass toindex
. However,S
andA
are only know when you callset
.The
apply
syntax has been created to guide type inference for such scenario, basicallyapplyOptional
capturesS
which isMap[Path, DirState]
. This gives enough information for the compiler to inferA =:= DirState
.