haskell - 使用镜头时变量不在范围内
问题描述
我遵循了砖蛇游戏的整个教程,但我遇到了这个错误
[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
to更改,_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
库有一个 Template Haskell 宏可以为您执行此操作,但您确实需要实际调用它!
data Game =
Game
{ _snake :: Snake -- ^ snake as a sequence of points in R2
, _dir :: Direction -- ^ direction
...
}
deriving (Show)
makeLenses ''Game
推荐阅读
- ios - 创建相机无法通过的实体场景包节点
- javascript - Javascript Youtube Data API v3:在播放列表中插入视频(找不到视频)
- angular - 模块中的 Angular 6 访问服务给出错误“模块没有导出成员”
- r - 如何使用 SHINY 中另一个脚本上的按钮运行另一个 rscript
- docker - 无法从外部主机访问 docker 容器中的服务器
- docker - 在执行“docker run”时获取当前指令的执行日志
- c++ - 表达式模板代码未完全优化
- c++ - C++ Windows 凭据提供程序进度屏幕
- youtube - Youtube API - 在普通帐户和品牌帐户之间切换
- javascript - 循环 ajax 结果并用 id 替换所有元素