Mentre si lavora su uno stato chiamato AppState
Voglio tenere traccia del numero di, per esempio, delle istanze. Queste istanze hanno ID distinti di tipo InstanceId
.Come utilizzare gli obiettivi per cercare un valore in una mappa, aumentarlo o impostarlo su un valore predefinito
Perciò il mio sguardo stato piace questo
import Control.Lens
data AppState = AppState
{ -- ...
, _instanceCounter :: Map InstanceId Integer
}
makeLenses ''AppState
La funzione per tenere traccia dei conteggi dovrebbe produrre 1 quando alcuna istanza con dato id è stato contato prima e n + 1
altrimenti:
import Data.Map as Map
import Data.Map (Map)
countInstances :: InstanceId -> State AppState Integer
countInstances instanceId = do
instanceCounter %= incOrSetToOne
fromMaybe (error "This cannot logically happen.")
<$> use (instanceCounter . at instanceId)
where
incOrSetToOne :: Map InstanceId Integer -> Map InstanceId Integer
incOrSetToOne m = case Map.lookup instanceId m of
Just c -> Map.insert instanceId (c + 1) m
Nothing -> Map.insert instanceId 1 m
Mentre il il codice sopra funziona, c'è sperabilmente un modo per migliorarlo. Quello che non mi piace:
- devo evocare la mappa
instanceCounter
due volte (prima per l'impostazione, quindi per ottenere il valore) - Io uso
fromMaybe
dove sempreJust
è previsto (quindi tanto vale usarefromJust
) - Non uso gli obiettivi per la ricerca e l'inserimento in
incOrSetToOne
. Il motivo è cheat
non consente di gestire il caso in cuilookup
produceNothing
ma invecefmap
s suMaybe
.
Suggerimenti per miglioramenti?
Mi sento come se non avessi capito fino in fondo ... ma ... ora il "Just ... Just' sembra ridondante. Devo sperimentare ancora, ma è proprio quello che stavo cercando. –
OK, quindi la chiave per me era capire la funzione [alter] (http://hackage.haskell.org/package/containers-0.5.6.3/docs/Data-Map-Strict.html#v:alter) che ha nella sua firma una funzione 'Maybe a -> Maybe a' per impostare o annullare i valori delle mappe. –
E in termini di miglioramento, le risposte di glguy superano le tue. Scusate! –