有人可以向我解释功能性镜片吗?对于Google来说,这是一个令人惊讶的困难,而且我没有取得任何进展。我所知道的是,它们提供与OO中类似的获取/设置功能。
Answers:
镜头包含两个功能,一个吸气器和一个设置器:
data Lens a b = 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 b c -> Lens a b -> Lens a c
compose f g = Lens (getter f . getter g) $
\c a -> setter g (setter f c (getter g a)) a
它们机械地转换为State
过渡:
lensGet :: MonadState s m => Lens s a -> m a
lensGet = gets . getter
lensSet :: MonadState s m => Lens s b -> b -> m ()
lensSet f = modify . setter f
lensMod :: MonadState s m => Lens s b -> (b -> b) -> m ()
lensMod f g = modify $ setter f =<< g . getter f
(+=) :: (MonadState s m, Num b) => Lens s b -> b -> m ()
f += x = lensMod f (+ x)
f
和g
。
请参阅问题镜头,fclabels,数据访问器的答案-哪个结构访问和突变库更好些-它在镜头上有非常清楚的解释。
此外,Data.Lenses和fclabel库的文档提供了一些很好的示例,说明了它们正在被使用。