我想从monad中提取值,但我无法弄清楚,我该怎么做?
问题出在available
函数中。
答案已经很少了,但在这里我有一个关于额外功能的具体问题,它只试图从IO monad获取价值。
main2 = do
fileName <- getLine
case (available fileName) of
False -> "Could not find the file"
True -> withFile fileName ReadMode (\handle -> do
contents <- hGetContents handle
putStrLn $ "Enter the name of second file"
secondName <- getLine
case (available fileName) of
False -> "could not find second file"
True -> withFile secondName AppendMode (\secondHandle -> do
hPutStrLn secondHandle contents
putStrLn $ "Done, copying file"))
这是我的可用功能,我想简单True
或False
。
我想我无法与IO
进行模式匹配,也无法弄清楚如何变得简单True
或False
?
available :: FilePath -> Bool
available fileName = case (doesFileExist fileName) of
IO True = True
IO False = False
答案 0 :(得分:4)
使用另一个&#34; bind&#34; (<-
)to&#34; get&#34;价值。重要的是要认识到<-
不是魔术;它重复调用我们用来组成IO
值函数的>>=
函数。
-- base
import System.IO (withFile, IOMode (..), hPutStrLn, hGetContents)
-- directory
import System.Directory (doesFileExist)
main2 :: IO ()
main2 = do
fileName <- getLine
available1 <- doesFileExist fileName
case available1 of
False -> putStrLn "Could not find the file"
True -> withFile fileName ReadMode $ \handle -> do
contents <- hGetContents handle
putStrLn "Enter the name of second file"
secondName <- getLine
available2 <- doesFileExist fileName
case available2 of
False -> putStrLn "could not find second file"
True -> withFile secondName AppendMode $ \secondHandle -> do
hPutStrLn secondHandle contents
putStrLn "Done, copying file"
您的额外功能 available
无法实施,因为该类型无法准确描述您想要的内容。
FilePath -> Bool
只是一个函数,从字符串到布尔值的映射。它不涉及任何人的文件系统的内容。函数是一种数学函数;它总是评估相同的结果,无论是评估它的计算机,还是我们用铅笔和纸来评估它。
doesFileExist :: FilePath -> IO Bool
是从字符串到 I / O操作的映射,它产生一个布尔值。 IO
值表示计算效果,而不是抽象的数学对象,因此这些值可以代表&#34;查看此计算机的文件系统等概念。&#34;
你永远不能离开IO,&#34;但幸运的是你并不需要,因为main2
的类型无论如何都是IO ()
。您的程序是由>>=
组合器组成的I / O操作构建的。