无法将预期类型“IO [String]”与实际类型“[String]”相匹配

Couldn't match expected type ‘IO [String]’ with actual type ‘[String]’

我有这两个代码片段,我猜它们做同样的事情,但它们没有。这是为什么?

这个很好用:

fdup :: String -> IO ()
fdup filename = do
        h <- openFile filename ReadMode
        c <- hGetContents h
        putStr $ unlines $ parse $ lines c
        hClose h

这个returns一个错误Couldn't match expected type ‘IO [String]’ with actual type ‘[String]’:

fdup' :: String -> IO ()
fdup' filename = do
        h <- openFile filename ReadMode
        c <- hGetContents h
        ls <- lines c
        putStr $ unlines $ parse $ ls
        hClose h

parse :: [String] -> [String]

它们有什么区别?

正如 Willem Van Onsem 所解释的那样,您不需要在那个特定位置使用 <-,因为 lines c 只是一个字符串列表,而不是 IO 计算。如果你想给它起一个名字,你可以使用 let-binding 代替:

fdup' :: String -> IO ()
fdup' filename = do
        h <- openFile filename ReadMode
        c <- hGetContents h
        let ls = lines c
        putStr $ unlines $ parse $ ls
        hClose h