4

我想试试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

到达这里

模棱两可的隐含值​​:类型的方法和类型的atMap方法都 匹配预期 类型 trait MapInstances[K, V]=> monocle.function.At[Map[K,V],K,V]atSettrait SetInstances[A]=> monocle.function.At[Set[A],A,Unit]monocle.function.At[S,Path,A]

试图将我的定义更改为

def setOpened(path: Path): StateStore => StateStore =
  index(path) composeLens DirState.opened set true

现在得到:

类型不匹配; found : monocle.function.Index[Map[Path,Nothing],Path,Nothing] (展开为) monocle.function.Index[Map[List[String],Nothing],List[String],Nothing] required: monocle.function.Index[Map[Path,Nothing],Path,A] (展开为)monocle.function.Index[Map[List[String],Nothing],List[String],A]

注意: Nothing <: A, 但trait Index类型不变A。您可能希望改为定义A+A。(SLS 4.5)

4

2 回答 2

9
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召唤一个 type 类的Index实例Index[S, I, A]。这允许使用indexfor MapListVector

问题是 scala 编译器需要推断 3 种类型SIAindex. I很简单,它是你传递给的参数的类型index。但是,S只有A当你打电话时才知道set

apply已创建语法来指导此类场景的类型推断,基本上捕获applyOptionalSwhich is Map[Path, DirState]. 这为编译器提供了足够的信息来推断A =:= DirState

于 2015-08-10T13:34:02.183 回答
0

Monocle 存储库中提供了许多有关如何执行此操作的示例以及许多其他方便的提示:

https://github.com/julien-truffaut/Monocle/blob/master/example/src/test/scala/monocle/function/

更具体地说,对于这种情况: https ://github.com/julien-truffaut/Monocle/blob/master/example/src/test/scala/monocle/function/FilterIndexExample.scala

于 2017-01-13T11:48:46.720 回答