什么是 Store in scalaz

What is Store in scalaz

我试图理解 scalaz 中的 Lenses(令人惊讶的是在 cats-core 中没有找到类似的东西)我遇到了所谓的 Store这是一个类型别名:

type StoreT[F[_], A, B] = IndexedStoreT[F, A, A, B]
type IndexedStore[I, A, B] = IndexedStoreT[Id, I, A, B]
type Store[A, B] = StoreT[Id, A, B]

哪里

final case class IndexedStoreT[F[_], +I, A, B](run: (F[A => B], I))

问题是如何对待这种类型?该文档仅引用 Lenses。谁能简单说一下?

对我来说,它看起来类似于 State monad,其中 "state transition" 存储函数 F[A => B]

一个Store[S,A]是一个充满A的结构,由S索引,区分S作为一种"cursor"进入结构。

要回答问题 "what is it?",最有指导意义的是查看它支持哪些操作。

可以查询光标位置:

_.pos : Store[S,A] => S

您可以"peek"光标下的值:

_.peek : Store[S,A] => A

您可以"seek"移动光标:

_ seek _ : (Store[S,A], S) => Store[S,A]

将其视为一个维度数组 S,数组中有一个索引 s:S,您可以移动索引。

例如,Store[(Int,Int), Byte]是一个二维的256色位图。您可以 peek 在光标下的像素的颜色(由一个字节表示),您可以使用 seek.

将光标移动到不同的像素

商店社区

Store[S,_] 也是一个comonad。这意味着它支持以下操作:

map : (A => B) => (Store[S,A] => Store[S,B])
extend : (Store[S,A] => B) => (Store[S,A] => Store[S,B])
duplicate : Store[S,A] => Store[S, Store[S, A]]

map 表示您可以使用函数更改商店中的所有值。

s.extend(f) 采用 "local" 计算 f,在 S 的特定位置对商店进行操作,并将其扩展到 "global"在每个位置对商店进行操作的计算。在位图示例中,如果您有一个函数 mean(store)store 中光标周围像素的平均值,那么 store.extend(mean) 将对整个图像执行高斯滤波器。新图像中的每个像素都是原始图像中该位置像素周围像素的平均值。

s.duplicate 给你一个充满 Store[S,A]Store[S,Store[S,A]],在每个位置 S 都有原始 Store[S,A] 的副本及其光标设置到该位置 S.

与国家的关系

StoreState 对偶 。在幕后,State[S,A] 实际上是 S => (A, S),而 Store[S,A] 实际上是 (S => A, S):

State[S,A] ~= S => (A, S)
Store[S,A] ~= (S => A, S)

都是由S => _(_, S)两个函子组成的。如果你以一种方式组合它们,你会得到 State[S,_]。如果你以另一种方式组合它们,你会得到 Store[S,_].

我就此发表过几次演讲:

https://www.youtube.com/watch?v=FuOZjYVb7g0

利用这种二元性的一个很酷的方法是,如果你有一个存储和一个状态机,它们就会相互消灭。 store 驱动状态机,而状态机又从 store 中选择一个值。

def zap[S,A,B](state: State[S,A], store: Store[S,B]): (A,B) = {
  val (a, s) = state.run(store.pos)
  (a, store.seek(s).peek)
}