预告,这是我在Haskell的第一天。
所以我有一个函数parse :: String -> String
,我试图通过标准传递一个文件,
input <- readFile "input.txt"
或其他标准,
handle <- openFile "input.txt" ReadMode
input <- hGetContents handle
我要执行的目标,
output <- unlines $ map parse $ lines input
(或者应该是规范格式化的)
现在据我所知,readFile返回一个字符串,lines接受一个字符串并返回一个字符串列表,map应该映射一个字符串列表。如果这是真的,那么为什么lines input
告诉我有一个[String]而不是String,而省略lines
而只是map parse input
告诉我它有一个字符串而不是一个字符串[字符串]?
答案 0 :(得分:6)
这是工作示例
parse :: String -> String
parse = id -- don't do anything to input
main = do
input <- readFile "input.txt"
let output = unlines $ map parse $ lines input
print output
在你的示例中,一切都很好,除了output <-
应该用let output =
代替,因为你可能还没有得到这个原因,根据你的措辞判断:readFile
返回一个串。正如评论中指出的那样,事实并非如此。它返回IO String
,这意味着您可以启动并获取字符串的IO动作(或者不是......如果文件不存在)。 <-
操作允许您检查此操作的正面结果:它表示当操作成功时,您将获得一个字符串(您称之为input
)。然后你可以玩它。
那么为什么<-
在第二行(lines
,map
和其他内容)不合适?仅仅因为它没有动作。您正在那里应用纯函数。绑定纯计算的结果是通过let smth =
完成的。
另外,请注意<-
以及let X =
属于do-blocks,用于编写一系列步骤来处理操作的语法结构。相反,在纯函数内部,您可以找到let X = … in
(注意in
)或where X =
来绑定中间结果。