Ключ доступа к карте - PullRequest
2 голосов
/ 14 марта 2019

У меня проблемы с использованием библиотеки линз для доступа к типу данных карты.

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 Ответ

3 голосов
/ 14 марта 2019

Это потому, что ix является Обходом, но use ожидает Объектив. Разница в том, что объектив всегда имеет ровно одну цель. Обход может иметь ноль или более. Комбинаторы, которые ожидают линзы при извлечении значений, случайно пытаются объединить несколько значений вместе как Monoid при получении обхода. (В частности, это происходит от экземпляра Applicative для Const.) Эта попытка не проверяет тип в вашем случае, потому что для целевого типа такого экземпляра не существует, поэтому вы получаете это сообщение об ошибке.

Возможно, вы хотите, чтобы комбинатор preuse вместо use учитывал значение, которое потенциально может отсутствовать.

...