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



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

我试过搜索,但似乎没有找到合适的答案,这可能吗?如有任何帮助,我们将不胜感激。

这是不可能的。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

有关更多信息,请参阅本常见问题解答和IO简介。

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不允许——它表示副作用,您不能从代码中删除副作用。

最新更新