镜头和棱镜
一个 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)
设置a
的a
插槽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