【问题标题】:How does IO monad work in System.RandomIO monad 如何在 System.Random 中工作
【发布时间】:2015-08-24 22:03:01
【问题描述】:
import System.Random

main = do
  g <- newStdGen
  a <-take 5 (randoms g :: [Double])
  return ()

所以这段代码不起作用,因为显然我分配给 a 的类型是 [Double] 而不是 IO [Double] 但我认为你永远无法逃离 IO?那么,即使 g 是 IO 类型,为什么我似乎已经从 IO 中逃脱了呢?我仍然对 IO monad 在 do 表示法中的工作方式感到困惑。

【问题讨论】:

  • 检查g的类型! g &lt;- newStdGen:type g 产生g :: StdGen。你无法逃脱,但你可以获取值并执行纯粹的计算。
  • 但是为什么第 2 行(在做)不编译
  • 第 2 行无法编译,因为 take 5 (randoms g :: [Double]) 不返回 IO(或 monadic)值。如果将行更改为let a = take 5 (randoms g :: [Double]),那么它应该可以编译。

标签: haskell io monads


【解决方案1】:

你无法逃离 IO,但在 do 块内你实际上并没有逃避本身。

松散地:当您在do 块中写入g &lt;- newStdGen 时,您可以稍后在块中使用g,就好像它只有类型StdGen,而不是IO StdGen。在块的末尾,您返回的任何内容都将被包裹在 IO 中。

【讨论】:

    【解决方案2】:

    使用 let a = 而不是 a &lt;-,因为 RHS 是一个纯值。

    import System.Random
    
    main = do
      g <- newStdGen
      let a = take 5 (randoms g :: [Double])
      print a
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-29
      • 2018-05-06
      • 2018-12-12
      相关资源
      最近更新 更多