I have some problems using Lens library to acces Map Data type.
data Card
= Ferme
| Boulangerie
data PlayerState = PlayerState {
_psCards :: Map Card Int,
} deriving (Show)
data GameState = GameState {
_gsPlayers :: [PlayerState]
} deriving (Show)
I have difficulties accessing the Map
step :: (MonadState s m, HasGameState s, MonadIO m) => m ()
step = do
i <- use $ gsPlayers . ix 0 . psCards . ix Ferme
with the following error:
• Could not deduce (Monoid Int) arising from a use of ‘ix’
from the context: (MonadState s m, HasGameState s, MonadIO m)
bound by the type signature for:
step :: forall s (m :: * -> *).
(MonadState s m, HasGameState s, MonadIO m) =>
m ()
Is this because I use ix
with different argument in the same line?
It's because ix
is a Traversal, but use
expects a Lens. The difference is that a Lens always has exactly one target. A Traversal can have zero or more. The combinators that expect lenses when retrieving a value sort of accidentally try to combine multiple values together as a Monoid
when given a Traversal. (It comes from the Applicative
instance for Const
, in particular.) That attempt doesn't type check in your case because no such instance exists for the target type, so you get that error message.
You probably want the preuse
combinator instead of use
, to account for the value potentially not being there.