haskell - 尝试编写nim游戏,我得到错误我不明白

时间:2013-12-05 16:42:49

标签: haskell

我试图在Haskell中编写游戏nim,但有些东西不起作用,我不知道为什么。 我有2个函数getRow和getNumber(它们都使用getInt,我也包括它),getRow以我想要的方式工作,但是使用getNumber我得到了sobe错误而且它不想加载。

getInt :: Int
getInt = do  
  s <- getLine
  read s

getRow :: [Int] -> (Int,Int) 
getRow board = do
  putStrLn "Give me row number "
  row <- getInt
  if ((length board) > (row-1)) && ((board!!(row-1)) > 0 )
    then (row, board!!(row-1))
    else do putStrLn "niepoprawny rzad"
            getRow board

getNumber :: [Int] -> (Int, Int) -> (Int, Int)
getNumber board row = do
  putStrLn "Give me number of stones you want to take"
  number <- getInt
  if number < 1 
    then do putStrLn "wrong number"
            getNumber board row
              else if (number > (snd row)) 
                   then ((fst row), 0)
                   else ((fst row), ((snd row) - number))

在getNumber中我得到:

 Couldn't match expected type '(Int, Int)' with actual type 'Int' 
 In a stmt of a 'do' block: number <- getInt"

我不了解任何一个。为什么getRow有效但getNumber没有?它们非常相似。

1 个答案:

答案 0 :(得分:5)

此代码中存在许多普遍存在的错误。最特别的是,纯粹的计算是在do块的最后一行完成的 - 这些必须return,以便它们最终“在IO”中。您的所有类型都没有在IO monad中返回。 if中的上一个getNumber语句中可能还有缩进错误。

getInt :: IO Int          -- in the IO monad
getInt = do  
  s <- getLine
  return (read s)         -- we must return pure values from monads

getRow :: [Int] -> IO (Int,Int)       -- in the IO monad
getRow board = do
  putStrLn "Give me row number "
  row <- getInt
  if ((length board) > (row-1)) && ((board!!(row-1)) > 0 )
    then return (row, board!!(row-1))   -- we must return pure values from monads
    else do putStrLn "niepoprawny rzad"
            getRow board

getNumber :: [Int] -> (Int, Int) -> IO (Int, Int)   -- in the IO monad
getNumber board row = do
  putStrLn "Give me number of stones you want to take"
  number <- getInt
  if number < 1 
    then do putStrLn "wrong number"
            getNumber board row
    else if (number > (snd row))                           -- better indentation
           then return ((fst row), 0)                      -- we must return
           else return ((fst row), ((snd row) - number))   -- we must return