这段代码怎么会进入死循环呢?也就是如何在 Haskell 中实现一个计数器?

How could this code enter an infinite loop? aka how to implement a counter in Haskell?

我将这段代码放在一个有副作用的函数中 ... -> IO()

let index_player = (-1)
dronePositionByPlayer <- replicateM nb_players $ do

    let index_player = index_player + 1

    dronePositions <- replicateM nb_drones $ do
        input_line <- getLine
        let input = words input_line 
        let dx = read (input!!0) :: Int 
        let dy = read (input!!1) :: Int
        let dronePosition = DronePosition (Position dx dy) index_player
        hPutStrLn stderr $ "position = " ++ show dronePosition
        return (dronePosition)
    return (dronePositions)

当我执行它时,在解析输入数据(这是几行,每行包含一个 x 和 y 位置)时,我在标准错误输出上有这个跟踪:

position = DronePosition (Position 703 892) Answer: <<loop>> 

显然它可以读取第一个位置,但随后进入无限循环,可能试图显示字段 index_player

DronePositionPosition 是简单的代数数据类型:

data Position = Position Int Int deriving Show
data DronePosition = DronePosition Position Drone deriving Show

我的代码中有什么格式错误的?

let index_player = index_player + 1

以上是一个递归定义,导致index_player变量通过递归加一来计算——永远。那不会终止。它不引用上面几行声明的同名变量。

如果你想要一个循环,你可以适应例如

xs <- forM [0..100] $ \i -> do
   print i
   return (1000 + i)

上面打印了0到100的所有数字,定义xs为所有返回数字的列表,即[1000..1100]。记得import Control.Monad使用forM.