使用镜头时变量不在范围内
我遵循了砖蛇游戏的整个教程,但我遇到了这个错误
[typecheck -Wdeferred-out-of-scope-variables] [E] • Variable not in scope:
paused :: Lens.Micro.Type.Getting Bool Game Bool
• Perhaps you meant ‘_paused’ (line 24)
完整代码在这里https://github.com/dhilst/brick-stake-tutorial-exercice-
重要的部分是这个
{-# LANGUAGE TemplateHaskell, FlexibleContexts #-}
module Snake where
import Control.Applicative ((<|>))
import Control.Monad (guard)
import Data.Maybe (fromMaybe)
import Data.Sequence (Seq, ViewL(..), ViewR(..), (<|))
import qualified Data.Sequence as S
import Lens.Micro ((%~), (&), (.~), (^.))
import Lens.Micro.TH (makeLenses)
import Linear.V2 (V2(..), _x, _y)
import System.Random (Random(..), newStdGen)
-- Types
data Game =
Game
{ _snake :: Snake -- ^ snake as a sequence of points in R2
, _dir :: Direction -- ^ direction
, _food :: Coord -- ^ location of the food
, _foods :: Stream Coord -- ^ infinite list of random food locations
, _dead :: Bool -- ^ game over flag
, _paused :: Bool -- ^ paused flag
, _score :: Int -- ^ score
, _frozen :: Bool -- ^ freeze to disallow duplicate turns
}
deriving (Show)
-- ...
step :: Game -> Game
step g =
fromMaybe g $ do
guard (not $ g ^. paused || g ^. dead)
let g' = g & frozen .~ False
return . fromMaybe (move g') $ die g' <|> eatFood g'
我以前从未使用过镜头。我厌倦了从paused到更改,_paused因为这是该字段的名称,但它给了我另一个错误
[typecheck -Wdeferred-type-errors] [E] • Couldn't match type ‘Bool’
with ‘Game -> Data.Functor.Const.Const Bool Game’
Expected type: Lens.Micro.Type.Getting Bool Game Bool
Actual type: Game -> Bool
• In the second argument of ‘(^.)’, namely ‘_paused’
In the first argument of ‘(||)’, namely ‘g ^. _paused’
In the second argument of ‘($)’, namely ‘g ^. _paused || g ^. dead’
镜头有什么魔力可以省略_我遗漏的吗?
回答
Haskell 不会自己生成镜头。(关于是否应该在某个时候进行一些讨论,但我认为它并没有走得太远。)
lens但是,该库有一个模板 Haskell 宏可以为您执行此操作,但您确实需要实际调用它!
data Game =
Game
{ _snake :: Snake -- ^ snake as a sequence of points in R2
, _dir :: Direction -- ^ direction
...
}
deriving (Show)
makeLenses ''Game