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

时间:2012-02-05 14:41:31

标签: haskell io

  

可能重复:
  Convert Haskell IO list to list type

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

2 个答案:

答案 0 :(得分:17)

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

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

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

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

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

有关详细信息,请参阅this FAQintroduction to IO

答案 1 :(得分:8)

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

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

do

这里,sumAll :: IO [[Int]] -> IO Int sumAll io_lists = do lists <- io_lists return $ sum $ map sum lists 绑定到执行IO操作的结果。因此,您可以毫无问题地将lists映射到它上面。 IO monad中的sum函数将valube“返回”到monad中,以便返回类型变为return。一些monad允许你从monad中取值,但IO不会 - 它代表副作用,你不能从代码中删除副作用。