[Haskell-cafe] Using State monad with lens

Matt Mongeau halogenandtoast at gmail.com
Sat Mar 21 18:51:21 UTC 2020


Which as others have mentioned, works well with lambda case, here's an
example from a game I am writing:

```
runPhase :: (MonadIO m, MonadState GameState m) => Card -> m ()
runPhase c at Card {..} = use phase >>= \case
  HeadlinePhase        -> liftIO . putStrLn $ "Drew: " ++ show c
  EventResolutionPhase -> liftIO . putStrLn $ "Event"
  ArmyMovementPhase    -> traverse_ moveArmy armyMovements
  ActionPhase          -> liftIO . putStrLn $ "Show me your moves!"
  KaiserschlachtPhase  -> pure ()
  NationalWillPhase    -> do
    nw <- nationalWill
    if nw <= -5 then gameOver else pure ()
  GameOver -> liftIO . putStrLn $ "Game over"
```

On Sat, Mar 21, 2020 at 11:34 AM Emily Pillmore <emilypi at cohomolo.gy> wrote:

> Normally, you'd write `gets` to access entries in your state environment
> according to some function (e.g. record accessors), but since
> `some_property` is itself (presumably) a `Lens` or `Getter`, you should be
> able to use the lensy-State accessor `use`(
> https://github.com/ekmett/lens/blob/e06c171840bbe86c789b8dff8c8211b88ac9211e/src/Control/Lens/Getter.hs#L347).
> Then, your script becomes:
>
> ```
> myFunc :: StateT MyState [ResultType]
> myFunc = do
>   p ← use some_property
>   case p of
>     True → do my_value .= "Hello"
>     False → do my_value .= "Goodbye"
> ```
>
> `use` works in the same sense that `view` does for `MonadReader r m ⇒ m`.
> It even has an analog to `preview` called `preuse`, which you can use for
> `Prism`s in your state environment.
>
> Cheers, hope that helps,
> Emily
>
>
>
> On Sat, Mar 21, 2020 at 10:42 AM, Michael Hull <mikehulluk at gmail.com>
> wrote:
>
>> Hi,
>> I use the State monad in a lot of places, but when I use it with the lens
>> library, I find myself writing code like:
>>
>> myFunc :: StateT MyState ([ResultType])
>> myFunc = do
>>    st <- get
>>    case st ^. some_property of
>>       True -> do
>>             my_value .= "Hello"
>>       True -> do
>>             my_value .= "Goodbye"
>>
>> I want to do something based on a 'state-variable', but I have to write
>> 'get' -- is there a pattern that allows me to avoid the intermediate 'st'
>> variable?
>> I want to write something like:
>>
>> myFunc = do
>>    case (get ^. some_property) of
>>       True -> do
>>             my_value .= "Hello"
>>       True -> do
>>             my_value .= "Goodbye"
>>
>> but that won't compile.
>>
>> Best wishes,
>>
>> Mike
>>
>>
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> To (un)subscribe, modify options or view archives go to:
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only
>> members subscribed via the mailman list are allowed to post.
>>
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20200321/2574b224/attachment.html>


More information about the Haskell-Cafe mailing list