gpt4 book ai didi

haskell - 如何简化 (IO (Either a b)) 中的错误处理

转载 作者:行者123 更新时间:2023-12-03 14:27:07 27 4
gpt4 key购买 nike

我以下面的场景为例来学习如何以简单的方式处理错误。该场景基本上是从环境变量中读取文件路径,然后使用文件路径读取并打印文件。

以下代码有效,但我不喜欢 printFile因为它嵌套了 case of ,有点难读。我想知道是否有一种干净的方法可以摆脱它并保留 printFile不使用 lookupEnv 的函数扁平化?

您将如何简化此错误处理流程?

module Main where

import Control.Exception (IOException, handle, throw)
import System.Environment (getEnv)
import System.IO.Error (isDoesNotExistError)

data MissingError
= MissingEnv String
| MissingFile String
deriving (Show)

main :: IO ()
main = do
eitherFile <- printFile
either print print eitherFile

getEnv' :: String -> MissingError -> IO (Either MissingError String)
getEnv' env err = handle (missingEnv err) $ Right <$> (getEnv env)

readFile' :: FilePath -> MissingError -> IO (Either MissingError String)
readFile' path err = handle (missingFile err) $ Right <$> (readFile path)

missingEnv :: MissingError -> IOException -> IO (Either MissingError String)
missingEnv err = const $ return $ Left err

missingFile :: MissingError -> IOException -> IO (Either MissingError String)
missingFile err e
| isDoesNotExistError e = return $ Left err
| otherwise = throw e

printFile :: IO (Either MissingError String)
printFile = do
eitherFilePath <- getEnv' "FOLDER" (MissingEnv "FOLDER")
case eitherFilePath of
Left err -> return $ Left err
Right path -> readFile' path (MissingFile path)

最佳答案

您可以使用 ExceptT monad 变压器。我没有尝试运行以下建议的更改,但它可以编译,所以我希望它可以工作。

首先,导入包含ExceptT的模块:

import Control.Monad.Trans.Except

接下来,更改 printFile功能:
printFile :: IO (Either MissingError String)
printFile = runExceptT $ do
path <- ExceptT $ getEnv' "FOLDER" (MissingEnv "FOLDER")
ExceptT $ readFile' path (MissingFile path)

您有返回 IO (Either MissingError String) 的函数,所以将它们包装在 ExceptT 中给你 do使您能够访问 String 的符号嵌入到有效的 ExcepT MissingError IO String 中.

然后打开 ExceptT返回值 runExceptT .

关于haskell - 如何简化 (IO (Either a b)) 中的错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53426475/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com