IO monad 如何在 System.Random 中工作

How does IO monad work in System.Random

import System.Random

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

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

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

松散地:当您在 do 块中写入 g <- newStdGen 时,您可以稍后在该块中使用 g 就好像它只有 StdGen 类型一样,而不是IO StdGen 个。在块的末尾,无论你 return 将被包裹在 IO.

使用 let a = 而不是 a <- 因为 RHS 是一个纯值。

import System.Random

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