ich mit freiem Monaden und Objektiv bin herumschlagen, die freie Monade mit meiner eigenen Version des IO Monade zu erstellen:Schwierigkeit mit Zoom und frei Monaden
data MyIO next
= LogMsg String next
| GetInput (String -> next)
deriving (Functor)
ich dies von einem Zustand Monade oben am Stapel etwa so: FreeT MyIO (State GameState) a
wo GameState
ist:
data GameState = GameState { _players :: [PlayerState] }
Nun, was ich möchte, ist ein Weg, um ein PlayerState
von einem GameState
Kontext „Zoom-in“. Etwas wie folgt aus:
zoomPlayer :: Int -> FreeT MyIO (State PlayerState) a -> FreeT MyIO (State GameState) a
zoomPlayer i prog = hoistFreeT (zoom (players . element i)) prog
Aber ich bin immer diese Fehlermeldung:
No instance for (Data.Monoid.Monoid a1)
arising from a use of ‘_head’
Dieser Fehler auf die Tatsache, dass scheint players . element i
ein Traversal ist; wenn ich den Listenaspekt von _players
entferne und normales Objektiv verwende, funktioniert der Code.
Irgendwelche Ideen zum Schreiben dieser Funktion?
Wäre es nicht einfacher, stattdessen 'StateT GameState (Free MyIO) a' zu haben? Wenn Sie später 'Free MyIO' für' IO' tauschen wollen, dann wäre dies der übliche Weg, da es keine Transformerversion von 'IO' gibt. – bheklilr
Das Problem rührt auch daher, dass das Indexieren einer Liste keine sichere Operation ist. Die Linsenbibliothek möchte, dass Sie einen Typ zurückgeben, der voreingestellt werden kann, und die Standardtypenklasse dafür ist "Monoid". Wenn Sie einfach 'Monoid a =>' zur Typ-Signatur von 'zoomPlayer' hinzufügen, werden Sie festgelegt. Das schränkt natürlich das ein, was Sie zurückgeben können, aber Sie müssen es tun, es sei denn, Sie möchten mehr Code schreiben. – bheklilr
@bheklir Mein schlechtes, das 'a' im Fehler war ein Tippfehler; es war wirklich 'a1'. Die Verwirrung tut mir leid. Es scheint, als wäre 'FreeF' das Ding, von dem es erwartet, dass es ein Monoid ist, aber ich habe keine Möglichkeit, eine Instanz dafür zu schreiben. Vielleicht könnte ich es vorübergehend in eine Liste einpacken und es dann auspacken. – Pubby