我们可以访问 do-block 中定义的 replicateM 的输出吗

Can we access the output from a replicateM defined in a do-block

假设我有这样的东西

main = do
    input_line <- getLine
    let n = read input_line :: Int

    replicateM n $ do
        input_line <- getLine
        let x = read input_line :: Int 

        return ()

 ***putStrLn $ show -- Can i access my replicateM here?
    return ()

我能否访问我的 replicateM 的结果,例如它是否是返回值,并打印出来。还是我必须在实际的 do 块中使用 replicateM?

replicateM n a returns a 返回值的列表。在你的情况下,这只是一个单位列表,因为你在末尾有 return (),但如果你用 return x 替换它,你将得到一个读取整数的列表。然后,您可以使用 <- 将其从 IO.

中取出

您还可以使用 readLine 代替 getLineread 来简化代码。同样 putStrLn . show 可以替换为 print.

main = do
    n <- readLn
    ints <- replicateM n readLn :: IO [Int]
    print ints

专攻IO

replicateM :: Int -> IO a -> IO [a]

这意味着它 returns 一个列表。所以在你的例子中你可以这样做:

results <- replicateM n $ do
    input_line <- getLine
    let x = read input_line :: Int
    return x   -- <- we have to return it if we want to access it

print results

当然可以。它的类型是 replicateM :: Monad m => Int -> m a -> m [a]。这意味着它可以出现在 do 块中 <- 的右侧:

    do
        ....
        xs <- replicateM n $ do { ... }
        ....

xs 将是 [a] 类型,通常用于绑定 Monad m => m [a].

的结果

不过,使用您的代码,在嵌套 do 中显示 return () 的地方,您将在 xs 中得到 ()s 复制 n 次].大概在实际代码中你会 return 那里有用的东西。