我有一个项目要为我需要从文件中读取的学校做,这是我必须实现的功能的负责人。
我已经提供了以下功能,我假设它读取名称为“ 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”功能的标题。
答案 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 String
和lines :: 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