2014-03-05 51 views
10

我需要一個鏡頭功能就像over,但一元操作:如何修改鏡頭使用monadic函數?

overM :: (Monad m) => Lens s t a b -> (a -> m b) -> (s -> m t) 

雖然這個功能很容易定義(它實際上只是一個身份模WrappedMonad),我不知道有這樣的功能某處定義在鏡頭

{-# LANGUAGE RankNTypes #-} 
import Control.Applicative 
import Control.Lens 

overF :: (Functor f) => Lens s t a b -> (a -> f b) -> (s -> f t) 
overF l = l 

overM :: (Monad m) => Lens s t a b -> (a -> m b) -> (s -> m t) 
overM l = (unwrapMonad .) . l . (WrapMonad .) 

回答

7
在Control.Lens.Traversal

traverseOf :: Over p f s t a b -> p a (f b) -> s -> f t 
traverseOf = id 

mapMOf :: Profunctor p => 
    Over p (WrappedMonad m) s t a b -> p a (m b) -> s -> m t 
mapMOf l cmd = unwrapMonad #. l (WrapMonad #. cmd) 

例子:

Prelude Control.Lens> traverseOf _1 (Just . (+2)) (2,2) 
Just (4,2) 

Prelude Control.Lens> mapMOf _1 (Just . (+2)) (2,2) 
Just (4,2) 
+0

'traverseOf'只是'id',它不會與AMP的問題有所幫助。你需要使用'WrappedMonad'固定鏡頭才能使用'traverseOf'。 –

+0

@ J.Abrahamson感謝您的澄清,在Traversal庫中添加了'mapMOf'定義。 –