什么是商店在scalaz

Som*_*ame 6 functional-programming scala scalaz scala-cats

我试图理解Lenses scalaz(令人惊讶的是没有发现类似的东西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]
Run Code Online (Sandbox Code Playgroud)

哪里

final case class IndexedStoreT[F[_], +I, A, B](run: (F[A => B], I))
Run Code Online (Sandbox Code Playgroud)

问题是如何对待这种类型?文档只是引用了Lenses.用几句话就可以解释一下吗?

对我来说,它看起来类似于Statemonad,其中"状态转换"存储功能F[A => B]

Apo*_*isp 9

A Store[S,A]是一个充满As 的结构,索引为S,具有区S分为结构的一种"光标".

要回答"它是什么?"这个问题,看看它支持的操作是最有启发性的.

您可以询问光标的位置:

_.pos : Store[S,A] => S
Run Code Online (Sandbox Code Playgroud)

您可以"查看"光标下的值:

_.peek : Store[S,A] => A
Run Code Online (Sandbox Code Playgroud)

你可以"寻找"移动光标:

_ seek _ : (Store[S,A], S) => Store[S,A]
Run Code Online (Sandbox Code Playgroud)

可以把它想象成一个维度数组S,在这里你有一个s:S数组的索引,你可以移动索引.

例如,Store[(Int,Int), Byte]是二维256色位图.您可以peek使用光标下像素的颜色(由字节表示),并且可以使用将光标移动到不同的像素seek.

商店comonad

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]]
Run Code Online (Sandbox Code Playgroud)

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

s.extend(f)采取"本地"计算f,该计算在特定位置处的商店上运行S,并将其扩展到在每个位置处在商店上运行的"全局"计算.在位图示例中,如果您有一个函数mean(store)可以获取光标周围的像素的平均值store,那么store.extend(mean)将对整个图像执行高斯滤镜.新图像中的每个像素将是紧邻原始图像中该位置处的像素的像素的平均值.

s.duplicate给你一个Store[S,Store[S,A]]完整的Store[S,A]s,在每个位置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)
Run Code Online (Sandbox Code Playgroud)

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

我几次谈了这个:

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

你可以利用这种二元性的一种很酷的方式是,如果你有一个商店和一个状态机,它们就会相互消灭.商店驱动状态机,然后状态机从商店中选择一个值.

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)
}
Run Code Online (Sandbox Code Playgroud)