【问题标题】:Haskell recursion in IO actionIO动作中的Haskell递归
【发布时间】:2019-03-26 16:17:37
【问题描述】:

仍然是一个初学者,无法在 IO 操作中找出递归循环。假设:

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

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

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

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

【问题讨论】:

  • 只要使用return ();这是创建IO () 值的最简单方法。
  • 否则不清楚你想要什么。你想要一个包含 10 个随机数的列表吗?
  • 照原样,fNoInspectPerHour 除了修改随机数生成器的状态之外并没有真正做任何事情;它不会对它生成的随机数做任何事情。

标签: haskell recursion io do-notation


【解决方案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 ()
    }

【讨论】:

    【解决方案2】:

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

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

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

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

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

    【讨论】:

    • ...sequencereplicate 的这种组合非常常见,以至于它有一个标准名称,replicateM
    • 哦,我以为存在,但似乎不在范围内。我必须先导入Control.Monad
    • 感谢@Chepner 和 Daniel Wagner。这当然帮助了我。还有很多东西要学。 Haskell 试图让它变得有趣。
    • 顺便说一下@Chepner:您的示例在提示符下工作,但是如何合并到do-block中......?
    • 为什么需要do 块?目前还不清楚fNoInspectPerHour 的目的是什么,因为它对生成的数字没有任何作用。
    猜你喜欢
    • 2011-09-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 1970-01-01
    相关资源
    最近更新 更多