2012-02-05 83 views

回答

17

这是不可能的。 IO [[Int]]不包含包含[[Int]];它是一个命令式程序的描述,它执行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 

this FAQintroduction to IO以获取更多信息。

+0

啊,很好,你扩大了你的答案,从而使我的答案大多是多余的:-) – 2012-02-05 14:53:14

8

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

要获得[[Int]]您需要执行的操作。您可以使用do表示法中的<-运算符。这给你执行操作的结果,然后你可以根据需要操作这个值。不过,您仍然需要迟早将值返回到IO monad。在具体的代码,它可以是这样的:

sumAll :: IO [[Int]] -> IO Int 
sumAll io_lists = do 
    lists <- io_lists 
    return $ sum $ map sum lists 

这里,lists势必执行IO操作的结果。因此,您可以将sum映射到其上而不会造成任何问题。来自IO monad的return函数将valube“返回”到monad中,以便返回类型变为IO Int。一些monad可以让你从monad中获取数值,但是IO不会 - 它代表副作用,并且你不能从代码中移除副作用。