Idiom używać do komponowania kilka procedur (z pamięcią) jest następujący:Jak uniknąć odwoływania się do wszystkich zmiennych stanu podczas aktualizowania tylko kilku?
p1 :: State (Int, String)()
p1 = do
(a, b) <- get
... do something ...
put (a', b)
p2 :: State (Int, String)()
p2 = do
(a, b) <- get
... do something else ...
put (a, b')
main = do
... initializing a0 b0 ...
print . flip evalState (a0, b0)
. sequence $ replicate 10 p1 ++ repeat p2
Jednakże, jak liczba zmiennej stanu rośnie, to szybko staje się dużo bardziej gadatliwy niż to konieczne:
p1 :: State (Int, String, Bool, Int, String, Bool)()
p1 = do
(a, b, c, d, e, f) <- get
... do something ...
put (a, b, c', d, e, f')
p2 :: State (Int, String, Bool, Int, String, Bool)()
p2 = do
(a, b, c, d, e, f) <- get
... do something ...
put (a', b', c, d, e, f)
main = do
print . flip evalState (a0, b0, c0, d0, e0, f0)
. sequence $ replicate 10 p1 ++ repeat p2
Jak się zastanawiałem, czy istnieje sposób aktualizacji tylko kilku zmiennych stanu bez konieczności odwoływania się do wszystkich nieużywanych? Myślałem coś w stylu IORef
, ale dla State
(w rzeczywistości jest pakiet stateref), ale nie jestem pewien, czy istnieją już pewne typowe idiomy, których używają inne osoby.
Czuję, że w tym przypadku lepiej pasuje do składni rekordu. Więc coś jak 'State MyState()' gdzie 'dane MyState = MyState {a :: Int, b :: String, c :: Bool, ...}'. – trVoldemort
Więc jeśli tylko 'a' jest aktualizacją, mogę po prostu napisać' put $ myState {a = a '} '. – trVoldemort
możesz również chcieć użyć rozszerzenia 'RecordWildCards' z nowym typem MyState' – jberryman