2014-03-05 9 views
10

Ich brauchte eine Linse Funktion, die wie over funktioniert, aber mit monadische Operationen:Wie kann man eine monadische Funktion mit Linsen ändern?

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

Während diese Funktion ist einfach zu definieren (es ist eigentlich nur eine Identität Modulo WrappedMonad), frage ich mich irgendwo solche Funktionen definiert in objektiv?

{-# 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 .) 

Antwort

7

in 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) 

Beispiel:

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' nur' id' ist, wird es nicht mit AMP Probleme helfen. Sie müssen Ihr 'WrappedMonad'-fixiertes Objektiv haben, um' traverseOf' zu verwenden. –

+0

@ J.Abrahamson Danke für die Klarstellung, hinzugefügt 'mapMOf' Definition aus der Traversal-Bibliothek. –

Verwandte Themen