镜头和棱镜

一个 Lens' s a 意味着你总能找到任何 s 中的 a。一个 Prism' s a 意味着你可以有时找到 s 实际上只是 a 但有时别的东西。

为了更清楚,我们有 _1 :: Lens' (a, b) a 因为任何元组总是有第一个元素。我们有 _Just::Prism' (Maybe a) a 因为有时 Maybe a 实际上是包含在 Just 中的 a 值,但有时它是 Nothing

有了这种直觉,一些标准组合器可以被解释为彼此平行

  • view::Lens' s a -> (s -> a)得到a 离开了 s
  • set::Lens' s a -> (a -> s -> s)设置aa 插槽
  • review::Prism' s a -> (a -> s)意识到一个 a 可能是一个 s
  • preview::Prism' s a -> (s -> Maybe a)试图将一个 s 变成一个 a

另一种思考方式是 Lens' s a 的值表明 s(r, a) 具有相同的结构,对于某些未知的 r。另一方面,Prism' s a 表明 s 具有与 Either r a 相同的结构。我们可以用以下知识编写上述四个函数:

-- `Lens' s a` is no longer supplied, instead we just *know* that `s ~ (r, a)`

view :: (r, a) -> a
view (r, a) = a

set::a -> (r, a) -> (r, a)
set a (r, _) = (r, a)

-- `Prism' s a` is no longer supplied, instead we just *know* that `s ~ Either r a`

review::a -> Either r a
review a = Right a

preview::Either r a -> Maybe a
preview (Left _) = Nothing
preview (Right a) = Just a