从'IO` Monad中获取价值

时间:2018-01-17 17:32:01

标签: haskell

我想从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"))

这是我的可用功能,我想简单TrueFalse。 我想我无法与IO进行模式匹配,也无法弄清楚如何变得简单TrueFalse

available :: FilePath -> Bool
available fileName  = case (doesFileExist fileName) of
                        IO True = True
                        IO False = False

1 个答案:

答案 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操作构建的。