我正在用Haskell创建一个简单的终端游戏,在实现健康系统时遇到了很大的困难。最后提出了将不断变化的健康点保存到文本文件中的想法,这样就可以将其作为一个"变量"。
我的代码:
readHealth = do
theFile <- openFile "health.txt" ReadMode
healthPoints <- hGetContents theFile
return healthPoints
这里的问题是,我无法访问readHealth之外的"healthPoints"。。。有什么建议吗?
这不是解决问题的合适方案。从IO
monad中提取数据是不可能的,因为这不是它的目的。相反,您应该考虑使用State
monad家族(或者它的近亲StateT
(,它允许您在整个程序中携带一个可变值,如下所示:
data Game = Game { health :: Int, ... }
type GameState = State Game
然后,要从主线程读取您的值,您可以使用:
gameloop :: GameState ()
gameloop = do
currentHealth <- gets health
pure ()
要更新健康状况,您需要一个简短的功能:
updateHealth :: Int -> Game -> Game
updateHealth newHealth game = game { health = newHealth }
然后你可以用将健康设置为10
gameloop :: GameState ()
gameloop = do
modify $ updateHealth 10
pure ()
用法示例:
> evalState (gets health) (Game { health = 10 })
10
> evalState (modify (updateHealth 20) >> gets health) (Game { health = 10 })
20
*实际上,使用unsafePerformIO
从IO
中提取值是可能的,但顾名思义,除非你真的知道自己在做什么,否则这样做是不安全的。