我尝试过搜索,但似乎没有找到合适的答案,这首先是可能的吗?对此有任何帮助表示赞赏。
答案 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 FAQ和introduction 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不会 - 它代表副作用,你不能从代码中删除副作用。