从`IO` Monad中获取价值 [英] Getting values out of `IO` Monad

查看:68
本文介绍了从`IO` Monad中获取价值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从monad中提取值,但我不知道,该怎么办?

I want to extract the values out of the monad but i can't figure out ,how can i do that?

问题出在可用函数中.

已经有很少的答案,但是在这里我有一个关于附加功能的具体问题,该功能仅尝试从IO monad获取价值.

There are already few answers but here i have specific question about an extra function which only tries to get value from 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 ?>

Here is my available function and i want simple True or False. I think i can't do pattern matching with IO and also can't figure out how do i get simple True or False?

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

推荐答案

使用另一个绑定"(<-)来获取"值.重要的是要领会<-并不是魔术.它代表对 >> = 函数,我们使用它来构成 IO 值的函数.

Use another "bind" (<-) to "get" the value. It's important to appreciate that <- is not magic; it repesents a call to the >>= function which we use to compose functions of IO values.

-- 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"

您的额外功能 可用无法实现,因为该类型无法准确描述您想要的含义.

Your extra function available is not possible to implement, because the type doesn't accurately describe what you want it to mean.

FilePath->Bool 只是一个函数,从字符串到布尔值的映射.它不涉及任何人的文件系统的内容.函数是数学函数;无论是在哪台计算机上进行评估,甚至是我们自己用铅笔和纸对它进行评估,它始终可以得出相同的结果.

FilePath -> Bool is just a function, a mapping from strings to booleans. It does not involve the contents of anyone's filesystem. A function is a mathematical function; it always evaluates to the same result, no matter whose computer it is evaluated on, or even if we evaluate it ourselves with pencil and paper.

doesFileExist :: FilePath->IO Bool 是从字符串到生成布尔值的 I/O操作的映射. IO 值表示计算效果,而不是抽象的数学对象,因此这些值可以表示诸如查看此计算机的文件系统"之类的概念.

doesFileExist :: FilePath -> IO Bool is a mapping from strings to I/O actions which produce a boolean. IO values represent computational effects, not abstract mathematical objects, and so these can represent concepts like "look at this computer's filesystem."

您永远不会摆脱IO",但幸运的是您不需要这样做,因为 main2 的类型仍然是 IO().您的程序是由由>> = 组合器组成的I/O操作构建的.

You can never "get out of IO," but fortunately you don't need to, because the type of main2 is IO () anyway. Your program is built of I/O actions composed with the >>= combinator.

这篇关于从`IO` Monad中获取价值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆