首页 > 解决方案 > 使用镜头时变量不在范围内

问题描述

我遵循了砖蛇游戏的整个教程,但我遇到了这个错误

[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'

我以前从没用过镜头。我厌倦了从pausedto更改,_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’

镜头有什么魔力可以让你忽略_我错过的吗?

标签: haskellhaskell-lens

解决方案


Haskell 不会自己生成镜头。(关于是否应该在某个时候进行一些讨论,但我认为它并没有走得太远。)

然而,该lens库有一个 Template Haskell 宏可以为您执行此操作,但您确实需要实际调用它!

data Game =
  Game
    { _snake :: Snake -- ^ snake as a sequence of points in R2
    , _dir :: Direction -- ^ direction
    ...
    }
  deriving (Show)

makeLenses ''Game

推荐阅读