如何将 IO 字符串转换为字符串 [duplicate]

How Do I convert IO String to a String [duplicate]

提问人:Daniel McAllister 提问时间:1/28/2023 最后编辑:JFMRDaniel McAllister 更新时间:1/29/2023 访问量:145

问:

我有一个包含以下数据的文本文件:

3
7 4
2 4 6
8 5 9 3

我想从本质上提取这些数据并以以下形式返回:

["3", "7 4", "2 4 6", "8 5 9 3"]

我曾经将整个文件作为单个字符串获取,然后使用行根据字符解析单个行。我尝试这样做,但我遇到的问题是返回,但我想要。代码如下:readFile'\n'readFileIO StringString

readLines :: FilePath -> [String]
readLines str = do
                  file <- readFile str
                  let list = lines (file :: String) 
                  list

我该如何处理这个问题?

字符串 解析 Haskell io

评论

5赞 chepner 1/28/2023
你没有;这应该是你了解类型的第一件事。你不会把数据拿出来;您可以通过(例如)使用 将值绑定到函数来构建新的 IO 操作。IO>>=
0赞 Daniel McAllister 1/29/2023
我现在明白了。你能详细说明一下装订部分吗?
0赞 chepner 1/29/2023
readLines "foo.txt" >>= someFunction将是一个 IO 操作,该操作在执行时执行 提供的操作,获取结果列表,并将其传递给 。( 本身必须是一个返回操作的函数。 实际上永远不会看到从 中读取的列表,但确实如此。readLines "foo.txt"someFunctionsomeFunctionIOfoo.txtsomeFunction

答:

4赞 chepner 1/28/2023 #1

其目的是防止您从 I/O 操作中提取数据。相反,您的函数还将返回一个 IO 操作,该操作在运行时执行将生成一个值列表。IO

readLines :: FilePath -> IO [String]
readLines str = do
                   file <- readFile str
                   let list = lines (file :: String)
                   return list

或者更简单地说,因为(像任何单子一样)是一个函子,IO

readLines :: FilePath -> IO [String]
readLines str = lines <$> readFile str

评论

0赞 Daniel McAllister 1/29/2023
这是有道理的。我的最终目标是从 readLines 获取输出并读取其中的各个字符串并创建一个 [Ints] 列表。即,[“3”, “7 4”, “2 4 6”, “8 5 9 3”] 变成 [[3], [7, 4], [2, 4, 6], [8, 5, 9, 3]]。但问题是,如果有意义,我无法对 IO [String] 执行列表操作。
0赞 chepner 1/29/2023
事实上。假设您想要列表的第一个元素。如果它是一个值,你可以使用(我们将忽略处理空列表的单独问题)。但是,由于它是 ,因此您只能创建另一个类型的操作,例如 。归根结底,每个Haskell程序都只是创建要在运行时执行的单个操作的练习。[String]headIO [String]IOIO Stringhead (readFile "foo.txt")IO ()
0赞 Louis Wasserman 1/29/2023
@DanielMcAllister:你要做的事情会是什么样子。do lines <- readLines file; print (listOperation lines)