0

仍然是一个初学者,无法弄清楚IO动作中的递归循环。认为:

fMinInspect :: Int
fMinInspect = 1
fMaxInspect :: Int
fMaxInspect = 12
-- fNoInspectPerHour :: IO ()
fNoInspectPerHour = do
  generateInspect <- randomRIO (fMinInspect,fMaxInspect)
  putStrLn ""

我想为我想要随机检查的 10 台机器生成一个列表,然后我可以重复调用一些可以将 10 倍添fNoInspectPerHour加到列表中的东西吗?

我尝试了一个外部函数,但我无法从IO (). 请注意,这putStrLn只是终止do-block,因为我不需要控制台输出。

PS。也欢迎在没有的情况下终止do-block 的建议。putStrLn

4

2 回答 2

2

randomIO (fMinInspect, fMaxInspect)是一个 IO 动作,一个类型的值(Num a, Random a) => IO a。(为简单起见,我们假设aInt现在开始。)请注意,动作的每次执行都可以生成不同的随机值;这就是作为生成随机值IO Int动作和作为随机值本身的区别。

一旦我们有了那个动作,我们就可以用replicate 10 (randomRIO (fMinInspect, fMaxInspect));创建一个动作列表。这将有[IO Int]10 个 IO 操作的类型。

sequence函数可以将您的 IO 操作列表更改为生成值列表的 IO 操作(每个值由相应操作生成),将 type 的值转换为 type[IO Int]的值IO [Int]

> fMinInspect = 1
> fMaxInspect = 12
> sequence (replicate 10 (randomRIO (fMinInspect, fMaxInspect)))
[1,6,6,1,7,5,8,4,7,7]

(这里,像往常一样,GCHi 正在执行由 生成的 IO 操作sequence,并返回该 IO 操作生成的结果。)

于 2018-10-22T15:00:25.560 回答
1

如果你真的打算在这里自己使用递归,你可以写例如

fNoInspectPerHour :: Int -> IO () 
fNoInspectPerHour 0 = return () 
fNoInspectPerHour n = do { 
    generateInspect <- randomRIO (fMinInspect,fMaxInspect) ; 
    --  Int            IO Int
    putStrLn generateInspect ;    -- or do some other IO action
    --                 IO ()
    fNoInspectPerHour (n-1) 
    --                 IO ()
    }
于 2018-10-22T17:26:30.950 回答