Haskell IO 动作中的递归
Haskell recursion in IO action
还是一个初学者,无法理解 IO
动作中的递归循环。假设:
fMinInspect :: Int
fMinInspect = 1
fMaxInspect :: Int
fMaxInspect = 12
-- fNoInspectPerHour :: IO ()
fNoInspectPerHour = do
generateInspect <- randomRIO (fMinInspect,fMaxInspect)
putStrLn ""
我想生成一个列表,比方说我要随机检查的 10 台机器,然后我可以重复调用将 10x fNoInspectPerHour
添加到列表中的东西吗?
我尝试了一个外部函数,但我无法从 IO ()
中获取操作。请注意 putStrLn
只是终止 do
块,因为我不需要控制台输出。
PS。关于在没有 putStrLn
的情况下终止 do
块的建议也欢迎。
randomIO (fMinInspect, fMaxInspect)
是一个IO动作,一个(Num a, Random a) => IO a
类型的值。 (为简单起见,我们假设 a
从现在开始就是 Int
。)
请注意,每次执行动作都会产生一个不同的随机值;这就是 IO Int
作为生成随机值的 动作 和本身就是随机值之间的区别。
一旦我们有了那个动作,我们就可以用 replicate 10 (randomRIO (fMinInspect, fMaxInspect))
创建一个动作列表;这将具有类型 [IO Int]
,IO 操作的 10 个副本。
sequence
函数可以将您的 IO 操作列表更改为生成值列表的 IO 操作(每个值由相应的操作生成),转换类型为 [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 正在执行由 sequence
生成的 IO 操作,并且 returns 由该 IO 操作生成的结果。)
如果你真的想在这里自己使用递归,你可以这样写
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 ()
}
还是一个初学者,无法理解 IO
动作中的递归循环。假设:
fMinInspect :: Int
fMinInspect = 1
fMaxInspect :: Int
fMaxInspect = 12
-- fNoInspectPerHour :: IO ()
fNoInspectPerHour = do
generateInspect <- randomRIO (fMinInspect,fMaxInspect)
putStrLn ""
我想生成一个列表,比方说我要随机检查的 10 台机器,然后我可以重复调用将 10x fNoInspectPerHour
添加到列表中的东西吗?
我尝试了一个外部函数,但我无法从 IO ()
中获取操作。请注意 putStrLn
只是终止 do
块,因为我不需要控制台输出。
PS。关于在没有 putStrLn
的情况下终止 do
块的建议也欢迎。
randomIO (fMinInspect, fMaxInspect)
是一个IO动作,一个(Num a, Random a) => IO a
类型的值。 (为简单起见,我们假设 a
从现在开始就是 Int
。)
请注意,每次执行动作都会产生一个不同的随机值;这就是 IO Int
作为生成随机值的 动作 和本身就是随机值之间的区别。
一旦我们有了那个动作,我们就可以用 replicate 10 (randomRIO (fMinInspect, fMaxInspect))
创建一个动作列表;这将具有类型 [IO Int]
,IO 操作的 10 个副本。
sequence
函数可以将您的 IO 操作列表更改为生成值列表的 IO 操作(每个值由相应的操作生成),转换类型为 [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 正在执行由 sequence
生成的 IO 操作,并且 returns 由该 IO 操作生成的结果。)
如果你真的想在这里自己使用递归,你可以这样写
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 ()
}