在过去的几周里,我一直在尝试独立学习 Haskell。目前,我正在尝试实现一个愚蠢的小猜谜游戏,其中计算机选择一个随机数,用户尝试猜测它。如果用户错了,程序会告诉用户答案更高或更低,并允许用户猜测,直到他们猜对为止。我已经让它工作了,但我想添加一个功能,以跟踪用户在每场游戏中的猜测次数,并在用户猜对后将该数字报告给用户。
来自命令式背景,自然要做的事情是有一个计数器,每次用户进行猜测时都会增加一个计数器,但在 Haskell 中你不能真正做到这一点(至少它看起来像一切的无状态和不变性会阻止这种情况)。
我玩弄了让 getGuess 和 giveHints 函数接受一个额外参数的想法,该参数表示到目前为止的猜测次数(我们称之为 numGuesses),并且在每次调用这些方法时,传递 (numGuesses+1)。但我无法让它发挥作用(更不用说我什至不知道这是否会奏效)。
我的代码如下。任何建议将不胜感激。我主要是在寻找想法,但也可以随意发布实际代码。另外,如果我的代码很糟糕,请随时告诉我,如果你发现任何令人发指的事情,我该如何改进它(我只在功能上编程了几个星期!)
import System.Random
import System.IO
import Control.Monad
main = do
gen <- getStdGen
let (ans,_) = randomR (1,100) gen :: (Int,StdGen)
putStrLn $ "I'm thinking of a number between 1 and 100..."
getGuess ans
putStrLn "You guessed it in __ guesses!"
putStr "Play again? "
hFlush stdout
desire <- getLine
when ((desire !! 0) `elem` ['y','Y']) $ do
putStrLn ""
newStdGen
main
getGuess ans = do
putStr "Your guess? "
hFlush stdout
guessStr <- getLine
giveHints ans (read guessStr)
giveHints ans guess = do
when (ans /= guess) $ do
if ans > guess
then putStrLn "It's higher."
else putStrLn "It's lower."
getGuess ans
注意:我使用的是 hFlush 标准输出,因为我使用的是行缓冲,没有它,一些交互的顺序就不是人们所期望的。