Menu

回溯 5 小时

…… 那么这次,也许能够出现新的“结局”吧

Lens Over Tea 笔记 1

因为发到 Medium 上会太丢人,所以发这里。

如果发现有什么错误,很可能是我错了。

类型

Lens s a  代表从 s 中获取 a,改变 s 中 a 的一个特殊结构。

例:Lens [a] a 代表:

  1. 我们可以从 [a] 中获取 a
  2. 我们可以在 [a] 中改变 a

例 2:Lens 可以代表:

  1. 我们可以从一个整数中获取这个整数的绝对值
  2. 我们可以从这个整数中改变这个整数的绝对值

比如说,假设我们有 x = -2 以及 y = 3, 假设我们用 Lens 以及同样的“操作函数”对 x 和 y 进行平方,那么运行结果是 f(x) = -4, f(y) = 9。

Lens s t a b 是 Generalized Lens,代表“整体结构”被从 s 变成了 t,“局部结构”从 a 变到了 b。

例:Lens [a] [a] a a 等价于 Lens [a] a,代表整体结构从 [a] 变到 [a],局部结构从 a 变到 a。

实现

我们先看一些有趣的结构:

我们仔细观察 Lens s t a b 的具体类型:

那么 Lens [a] [a] a a 等价于:

即为:

  1. 给我两个输入
  2. 第一个输入是一个 a -> f a,即一个将列表内元素映射到“包含”这个列表内元素的““容器(Functor)””内。
  3. 第二个输入是列表本身
  4. 最后返回结果为之前设置的“容器”,会包含一个最终“更新过”的列表本身

如果我们用 Identity 作为容器的话,那么结果如下:

“简化”之后就是:

就是普通的函数式列表更新。

如果我们采用 Const 作为容器的话,那么结果如下:

但是我们只能获得 Const 的第一个类型的结果,所以 Const a [a] 的 [a] 是永远获取不了的,我们只能获取 Const a [a] 的 a,也就是我们需要的“读取”效果。

例:

这样也就成功利用 Functor 和 Lens 的结构来做到:“一个函数结构,但是可以用来改变结构也可以用来读取结构”

 

发表评论