【发布时间】:2019-05-11 17:32:37
【问题描述】:
我有这两个代码 sn-ps,我猜它们会做同样的事情,但他们没有。这是为什么呢?
这个很好用:
fdup :: String -> IO ()
fdup filename = do
h <- openFile filename ReadMode
c <- hGetContents h
putStr $ unlines $ parse $ lines c
hClose h
这个返回错误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]
它们有什么区别?
【问题讨论】:
-
错误可能位于
ls <- lines c? -
是的,但我不明白为什么......
-
因为如果你写
x <- some_expr,那么some_expr需要是Monad m => m a类型,然后x是a类型。在整个do块中,一个使用相同的单子m。不幸的是,do表示法可能表明这只是一种不同的“风格”。但实际上这里的 monad 发挥了作用。简而言之,Haskell 是一种纯函数式语言,使用相同参数的调用总是给出相同的结果。有状态的动作,如打开文件等,因此需要一个状态。 monad 可以用于隐式传递该状态。 -
现在我清楚了,谢谢你的解释!
-
@WillNess 为什么要涉及
<-或return?为什么不只是let ls = lines c?