功能镜片


80

有人可以向我解释功能性镜片吗?对于Google来说,这是一个令人惊讶的困难,而且我没有取得任何进展。我所知道的是,它们提供与OO中类似的获取/设置功能。


7
一个很好的介绍,镜头由爱德华Kmett YouTube上。例子在Scala中,但是应该很容易理解。
hammar

是的,试图观看这些节目,但是在我仍然保持警觉的同时有足够的时间并不是那么容易:P
Masse

2
@Jochen:那里描述的镜片与这个问题所涉及的镜片并没有太多共同点。
sclv 2011年

3
这是使用图片的不错介绍:图片中的镜头
Debjit

Answers:


61

镜头包含两个功能,一个吸气器和一个设置器:

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)

您的撰写示例未进行类型检查。GHC推断;Lens aa-> Lens aa-> Lens aa
Masse

Masse:我不小心翻转了fg
Apocalisp

它仍然没有在a-> c中键入check。它推断为撰写:: Lens ab-> Lens aa-> Lens ab
Masse

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.