什么是 Store in scalaz
What is Store in scalaz
我试图理解 scalaz
中的 Lens
es(令人惊讶的是在 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))
问题是如何对待这种类型?该文档仅引用 Lens
es。谁能简单说一下?
对我来说,它看起来类似于 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
.
与国家的关系
Store
是 State
的 对偶 。在幕后,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)
}
我试图理解 scalaz
中的 Lens
es(令人惊讶的是在 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))
问题是如何对待这种类型?该文档仅引用 Lens
es。谁能简单说一下?
对我来说,它看起来类似于 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
.
与国家的关系
Store
是 State
的 对偶 。在幕后,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)
}