У меня есть следующий код. Я хотел бы иметь возможность изменять жизнь активного игрока при задании состояния игры. Я придумал объектив activePlayer
, но когда я пытаюсь использовать его в сочетании с оператором -=
, я получаю следующую ошибку:
> over (activePlayer.life) (+1) initialState
<interactive>:2:7:
No instance for (Contravariant Mutator)
arising from a use of `activePlayer'
Possible fix:
add an instance declaration for (Contravariant Mutator)
In the first argument of `(.)', namely `activePlayer'
In the first argument of `over', namely `(activePlayer . life)'
In the expression: over (activePlayer . life) (+ 1) initialState``
и рассматриваемый код:
{-# LANGUAGE TemplateHaskell #-}
module Scratch where
import Control.Lens
import Control.Monad.Trans.Class
import Control.Monad.Trans.State
import Data.Sequence (Seq)
import qualified Data.Sequence as S
data Game = Game
{ _players :: (Int, Seq Player) -- active player, list of players
, _winners :: Seq Player
}
deriving (Show)
initialState = Game
{ _players = (0, S.fromList [player1, player2])
, _winners = S.empty
}
data Player = Player
{ _life :: Integer
}
deriving (Show, Eq)
player1 = Player
{ _life = 10
}
player2 = Player
{ _life = 10
}
makeLenses ''Game
makeLenses ''Player
activePlayer
:: (Functor f, Contravariant f) =>
(Player -> f Player) -> Game -> f Game
activePlayer = players.to (\(i, ps) -> S.index ps i)
Каждый игрок делает свой ход по порядку. Мне нужно отслеживать всех игроков одновременно, а также тех, кто в данный момент активен, что является причиной того, как я это структурировал, хотя я открыт для разных структур, поскольку у меня, вероятно, еще нет подходящей.
activePlayer
позволяет ему действовать как геттер, но не как сеттер - вы сказали ему, как вытащить игрока из Последовательности, но не как изменить активного игрока - поэтому он нельзя использовать для модификации игроков. Проверьте типto
---> :i to
приводит кto :: (a -> c) -> Getter a b c d
- person Chris Taylor   schedule 12.12.2013