2014-07-01 3 views
6

Das Problem ist ziemlich einfach. Ich habe eine Struktur, die so etwas wie diesesWie kann ich "over" von Control.Lens verwenden, aber eine monadische Aktion ausführen und die Ergebnisse sammeln?

data Foo = Foo [Bar] 
data Bar = Boo | Moo Item Int 
data Item = Item String Int 

und ich habe eine Linse zum Ändern des Inhalts der Item s innerhalb der Datenstruktur, wie diese hier

let foos = [Foo [Boo, Moo (Item "bar" 20) 10]] 
over (traverse._Foo._Moo._1._Item._1) ("foo" ++) foos 

-- which yields [Foo [Boo, Moo (Item "foobar" 20) 10]] 

Die Struktur aussieht, ist nicht wichtig, ich wollte nur ein Beispiel zeigen, das Prismen und etwas tief verschachteltes verwendet.

Nun ist das Problem, dass ich die Funktion overString -> IO String statt String -> String übergeben muss. Eine ähnliche Sache, nach der ich hier suche, ist etwas wie mapM, aber mit Linsen. Ist es möglich, so etwas zu tun?

Antwort

10

Objektiv bietet die traverseOf Funktion, die genau wie mapM ist aber nimmt eine linsenartige (es dauert eine Traversal, die Linsen und Prims enthält), über die Sie map wollen.

traverseOf :: Functor f => Iso s t a b  -> (a -> f b) -> s -> f t 
traverseOf :: Functor f => Lens s t a b  -> (a -> f b) -> s -> f t 
traverseOf :: Applicative f => Traversal s t a b -> (a -> f b) -> s -> f t 

So für Ihr Beispiel, die Sie gerade verwenden können:

traverseOf (traverse._Foo._Moo._1._Item._1) (... expression of type String -> IO String ...) foos 

Es gibt auch eine Operator-Version von traverseOf, genannt %%~.


Wenn Sie ein bisschen familar mit der Darstellung von Linsen im Objektiv Bibliothek sind, könnten Sie, dass traverseOf = id bemerken! Also, mit diesem Wissen können Sie das Beispiel umschreiben nur (! Du bin sogar traverse, die gerade mapM ist die Traversal zu bauen Linsen Prims/sind wie traverse, aber präziser.)

(traverse._Foo._Moo._1._Item._1) (... expression of type String -> IO String ...) foos 

Aber das ist nur eine Seite, möchten Sie dennoch traverseOf für die Übersichtlichkeit verwenden möchten.

Verwandte Themen