zoom
allows us to use a state action that only uses some state variables, in a context where more variables are actually defined.
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
import Control.Monad.Trans.State
import Control.Monad.IO.Class
data Galaxy = Galaxy {
_solarSys :: SolarSystem
, _otherStars :: String
} deriving (Show)
data SolarSystem = SolarSystem {
_sun :: Float
, _planets :: Int
} deriving (Show)
makeLenses ''SolarSystem
makeLenses ''Galaxy
main = (`runStateT`Galaxy (SolarSystem 2e+30 8) "") $ do
zoom solarSys $ do
sun -= 1e+23
planets += 1
liftIO . print =<< get
Galaxy {_solarSys = SolarSystem {_sun = 1.9999999e30, _planets = 9}, _otherStars = ""}
But what if I want to do some stuff in an environment with only some state variables defined, and then run a computation that has some extra, local state-variables? Like
data Expedition = Expedition {
_environment :: SolarSystem
, _spacecraft :: Char
} deriving (Show)
makeLenses ''Exploration
main = (`runStateT`Galaxy (SolarSystem 2e+30 8) "Milky") $ do
zoom solarSys $ do
spectralFilter environment (spacecraft ???~= '') $ do
spacecraft .= '️'
environment . planets -= 1
liftIO . print =<< get
I suspect the initialisation of spacecraft
would actually require some other optic, but I can't see which.