function性镜头

有人可以向我解释function镜头吗? 这是一个令人惊讶的困难的主题谷歌,我没有取得任何进展。 我所知道的是他们提供了类似的获取/设置function比OO。

一个镜头包含两个function,一个吸气剂和一个setter:

data Lens ab = Lens { getter :: a -> b, setter :: b -> a -> a } 

例如,我们可能会为一对的第一部分和第二部分配备镜头:

 fstLens :: Lens (a, b) a fstLens = Lens fst $ \x (a, b) -> (x, b) sndLens :: Lens (a, b) b sndLens = Lens snd $ \x (a, b) -> (a, x) 

镜头真正的便利是他们组成:

 compose :: Lens bc -> Lens ab -> Lens ac compose fg = Lens (getter f . getter g) $ \ca -> setter g (setter fc (getter ga)) a 

他们机械地转换为State转换:

 lensGet :: MonadState sm => Lens sa -> ma lensGet = gets . getter lensSet :: MonadState sm => Lens sb -> b -> m () lensSet f = modify . setter f lensMod :: MonadState sm => Lens sb -> (b -> b) -> m () lensMod fg = modify $ setter f =<< g . getter f (+=) :: (MonadState sm, Num b) => Lens sb -> b -> m () f += x = lensMod f (+ x) 

看问题的答案镜头,fclabels,数据存取器 – 哪个库的结构访问和突变更好 – 它有一个非常清晰的镜头解释。

另外, Data.Lenses和fclabel库的文档给出了一些很好的例子。