如何使用单片眼镜更新地图
How to update Map using monocle
我想试试 Monocle 图书馆。
但是我找不到基本语法的帮助资源。
简而言之,我需要光学器件 Map[K,V] -> A
具有光学器件 V -> A
,我该如何定义它?
假设我有一些
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]
接下来我遇到需要简单的地方StateStore => StateStore
,所以我正在导入
import monocle._
import monocle.std._
import monocle.syntax._
import monocle.function._
并首先尝试定义:
def setOpened(path: Path): StateStore => StateStore =
at(path) composeLens DirState.opened set true
到达此处
ambiguous implicit values: both method atMap
in trait MapInstances
of
type [K, V]=> monocle.function.At[Map[K,V],K,V]
and method atSet
in
trait SetInstances
of type [A]=> monocle.function.At[Set[A],A,Unit]
match expected type
monocle.function.At[S,Path,A]
试图将我的定义更改为
def setOpened(path: Path): StateStore => StateStore =
index(path) composeLens DirState.opened set true
现在开始:
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
, but trait Index
is invariant in type A
. You may wish to
define A
as +A
instead. (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)
我们来看看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]
}
所以index
召唤一个类型classIndex
类型Index[S, I, A]
的实例。
这允许对 Map
、List
、Vector
等使用 index
。
问题是 scala 编译器需要在 index
的调用位置推断出 3 种类型:S
、I
和 A
。 I
很简单,就是你传给index
的参数类型。但是,S
和 A
只有在调用 set
时才知道。
已创建 apply
语法来指导此类场景的类型推断,基本上 applyOptional
捕获 S
即 Map[Path, DirState]
。这为编译器提供了足够的信息来推断 A =:= DirState
.
Monocle 存储库中提供了很多如何执行此操作的示例以及许多其他方便的技巧:
https://github.com/julien-truffaut/Monocle/blob/master/example/src/test/scala/monocle/function/
我想试试 Monocle 图书馆。 但是我找不到基本语法的帮助资源。
简而言之,我需要光学器件 Map[K,V] -> A
具有光学器件 V -> A
,我该如何定义它?
假设我有一些
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]
接下来我遇到需要简单的地方StateStore => StateStore
,所以我正在导入
import monocle._
import monocle.std._
import monocle.syntax._
import monocle.function._
并首先尝试定义:
def setOpened(path: Path): StateStore => StateStore =
at(path) composeLens DirState.opened set true
到达此处
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]
试图将我的定义更改为
def setOpened(path: Path): StateStore => StateStore =
index(path) composeLens DirState.opened set true
现在开始:
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)
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)
我们来看看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]
}
所以index
召唤一个类型classIndex
类型Index[S, I, A]
的实例。
这允许对 Map
、List
、Vector
等使用 index
。
问题是 scala 编译器需要在 index
的调用位置推断出 3 种类型:S
、I
和 A
。 I
很简单,就是你传给index
的参数类型。但是,S
和 A
只有在调用 set
时才知道。
已创建 apply
语法来指导此类场景的类型推断,基本上 applyOptional
捕获 S
即 Map[Path, DirState]
。这为编译器提供了足够的信息来推断 A =:= DirState
.
Monocle 存储库中提供了很多如何执行此操作的示例以及许多其他方便的技巧:
https://github.com/julien-truffaut/Monocle/blob/master/example/src/test/scala/monocle/function/