三个月后更新
下面我使用netwire-5.0.1
+ sdl
给出了一个答案,在一个使用Arrow和Kleisli的函数式反应编程结构中,I/O虽然太简单,不能被称为“游戏”,但它应该是非常可组合的和非常可扩展的。
原始
我只是在学习Haskell,试着用它做一个小游戏。然而,我想看看一个小的(规范的)文本游戏可以是什么结构。我还尽量保持代码的纯洁性。我现在很难理解如何实施:
State
和/technical/game-programming/haskell-game-object-design-or-how-functions-can-get-you-apples-r3204中的一些东西,但是尽管单个组件可以在有限的步骤中工作和更新,但我不知道如何在无限循环中使用它。如果可能的话,我希望看到一个最基本的例子:
我没有任何的邮政编码,因为我不能得到非常基本的东西。我在网上找到的任何其他材料/例子都可以使用其他库,比如SDL
或GTK
来驱动事件。我找到的唯一一个完全用Haskell编写的是http://jpmoresmau.blogspot.com/2006/11/my-first-haskell-adventure-game.html,但它在主循环中看起来也不像尾递归(同样,我不知道这是否重要)。
或者,哈斯克尔可能不打算做这样的事?或者我应该把main
放在C里?
编辑1
因此,我在use中修改了一个小示例,使它更加简单(而且它不符合我的标准):
module Main where
import Control.Monad.State
main = do
putStrLn "I'm thinking of a number between 1 and 100, can you guess it?"
guesses <- execStateT (guessSession answer) 0
putStrLn $ "Success in " ++ (show guesses) ++ " tries."
where
answer = 10
guessSession :: Int -> StateT Int IO ()
guessSession answer =
do gs <- lift getLine -- get guess from user
let g = read gs -- convert to number
modify (+1) -- increment number of guesses
case g of
10 -> do lift $ putStrLn "Right"
_ -> do lift $ putStrLn "Continue"
guessSession answer
但是,它最终会溢出内存。我用
bash prompt$ yes 1 | ./Test-Game
内存使用量开始线性增长。
编辑2
好吧,我找到了Haskell recursion and memory usage并对“堆栈”有了一些了解.所以我的测试方法有什么问题吗?
发布于 2015-06-18 14:36:34
您的问题是,您使用的是StateT转换器的惰性版本,它从重复的modify
中构建了一个巨大的重击(因为它们从未被完全评估过)。如果您转而导入Control.Monad.State.Strict
,它可能会在没有溢出的情况下正常工作。
https://stackoverflow.com/questions/30905930
复制相似问题