#haskell #haskell-lens
#haskell #haskell-lens
Вопрос:
У меня возникли некоторые проблемы с использованием библиотеки Lens для доступа к типу данных карты.
data Card
= Ferme
| Boulangerie
data PlayerState = PlayerState {
_psCards :: Map Card Int,
} deriving (Show)
data GameState = GameState {
_gsPlayers :: [PlayerState]
} deriving (Show)
У меня возникли трудности с доступом к Map
step :: (MonadState s m, HasGameState s, MonadIO m) => m ()
step = do
i <- use $ gsPlayers . ix 0 . psCards . ix Ferme
со следующей ошибкой:
• 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 ()
Это потому, что я использую ix
с другим аргументом в одной строке?
Ответ №1:
Это потому, что ix
это обход, но use
ожидает объектива. Разница в том, что объектив всегда имеет ровно одну цель. Обход может содержать ноль или более. Комбинаторы, которые ожидают, что линзы при извлечении значения как бы случайно пытаются объединить несколько значений вместе как Monoid
при заданном обходе. (В частности, он поступает из Applicative
экземпляра для Const
.) Эта попытка не приводит к проверке типа в вашем случае, потому что для целевого типа не существует такого экземпляра, поэтому вы получаете это сообщение об ошибке.
Вероятно, вы хотите, чтобы preuse
combinator вместо use
учитывал значение, которого там потенциально нет.