无法将类型“ IO字符串”与“ [字符]”匹配

时间:2019-04-09 10:35:50

标签: string file haskell io

我有一个项目要为我需要从文件中读取的学校做,这是我必须实现的功能的负责人。

我已经提供了以下功能,我假设它读取名称为“ file_name”的文件:

getInputTest file_name = do  
    x <- readFile file_name
    return x

接下来,我必须解析文本的每一行,以便获得Strings的向量,向量的每个元素都是文件的一行。这是我要实现的功能的开头:

parse :: String -> [Instr]

此函数的第一个参数应该是从文件中读取的所有内容(所有行),[Instr]应该由文件中的所有行组成,向量的每个元素都是一行。(“ Instr”应该由我选择,而我尝试将其选择为“ String”,但这不起作用)

我已经尝试过了:

parse file_name = lines (getInputTest file_name)

但是我不断收到错误消息,例如:“无法将类型'IO String'与'[Char]'相匹配”。

我在做什么错,我该如何解决?考虑到不应修改“ parse”功能的标题。

2 个答案:

答案 0 :(得分:1)

String[Char],因此编译器抱怨它包装在IO中。阅读例如。 https://wiki.haskell.org/Introduction_to_IO进行解释。

要修复此问题,您需要在其调用点“提升”解析函数,以对IO String进行操作。这通常需要例如。 fmap / <$>,但是使用do表示法,则可以通过编写例如来加糖。 return $ parse x

答案 1 :(得分:0)

getInputTest file_name = do  
    x <- readFile file_name
    return x

这等效于以下任何一项:

getInputTest :: FilePath -> IO String
getInputTest fileName = readFile fileName >>= \x -> return x
getInputTest fileName = readFile fileName >>= return
getInputTest fileName = readFile fileName
getInputTest = readFile
parse :: String -> [Instr]
parse file_name = lines (getInputTest file_name)

getInputTest :: FilePath -> IO Stringlines :: String -> [String]起,正如泰勒所说,您必须 lift lines使其在IO的上下文中起作用

进行fmap lines时,您会得到类型Functor f => f String -> f [String],当将f专门化为IO时,它会变成IO String -> IO [String]。这与readFile的输出类型匹配,因此函数可以组成:

parse :: FilePath -> IO [String]
parse fileName = fmap lines (getInputTest fileName)

我不确定Instr是哪种类型,以及是否比lines进行进一步的解析才能将String的行转换为Instr;如果没有,也许您可​​以将这两个功能合而为一:

type Instr = String

fromFile :: FilePath -> IO [Instr]
fromFile = fmap lines . readFile