如何在Haskell中将IO [[Int]]转换为[[Int]]?

n00*_*00b 1 io haskell

可能重复:
将Haskell IO列表转换为列表类型

我试过搜索但似乎没有找到合适的答案,这首先是可能的吗?对此有任何帮助表示赞赏.

ehi*_*ird 17

这是不可能的.一个IO [[Int]]包含[[Int]]; 它描述了执行IO的命令性程序,当执行IO时,它将产生类型的结果[[Int]].这样的描述永远不会被执行,或者执行任何次数([[Int]]每次都产生,并且不一定是相同的).

Haskell是一种纯语言,因此无法IO直接执行描述; 相反,您可以将它们组成更大的描述.要使IO实际发生,您可以定义main为一个IO动作,然后在程序运行时执行; 或者您可以在GHCi中输入IO操作(例如putStrLn "Hello, world!"),GHCi将运行它们.

编写IO动作的最简单方法是使用do符号,您可能已经使用过该符号.这是一个例子:

myAction :: IO [[Int]]
myAction = ...

main :: IO ()
main = do
    xs <- myAction
    -- now xs is a normal value with type [[Int]]
    print xs
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅此常见问题解答IO简介.


Mar*_*ler 8

ehird的答案是正确的 - 类型的值IO [[Int]]是如何获取整数列表的描述.这也称为动作.

为了获得执行操作[[Int]]所需的操作.您可以使用符号表示操作员.这为您提供了执行操作的结果,然后您可以根据需要对此值进行操作.不过,您仍需要迟早将值重新放入IO monad中.在具体的代码中,它看起来像这样:<-do

sumAll :: IO [[Int]] -> IO Int
sumAll io_lists = do
  lists <- io_lists
  return $ sum $ map sum lists
Run Code Online (Sandbox Code Playgroud)

这里,lists绑定到执行IO操作的结果.因此,您可以sum毫无问题地映射它.returnIO monad中的函数将valube"后退"放入monad中,以便返回类型IO Int.有些monad允许你从monad中取值,但IO不能 - 它代表副作用,你无法从代码中删除副作用.