首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么“首先”不从Data.Bifunctor转换这个值?

为什么“首先”不从Data.Bifunctor转换这个值?
EN

Stack Overflow用户
提问于 2019-08-02 11:28:51
回答 1查看 83关注 0票数 3

在以下方面:

代码语言:javascript
复制
import Data.Bifunctor
import qualified Data.ByteString.Lazy.UTF8 as BLU

safeReadFile :: FilePath -> ExceptT Text IO Text
safeReadFile p = (lift $ doesFileExist p) >>= bool (throwError "File does not exist") (lift $ pack <$> readFile p)

safeDecodeJSONFile :: FromJSON a => Text -> FilePath -> ExceptT Text IO a
safeDecodeJSONFile t f = do
  contents <- safeReadFile f
  tryRight $ first (\x -> pack (x ++ (unpack t))) (eitherDecode (BLU.fromString (unpack contents)))

当我运行runExceptT $ safeDecodeJSONFile "something" "nonExistantFile.json"时,我希望得到Left "Does not exist something",但是我只是得到了Left "Does not exist" --我知道我传递给first的函数正在被执行,因为没有pack GHC就会抱怨(eitherDecode (BLU.fromString (unpack contents)))的类型是ExceptT String IO a而不是ExceptT Text IO a --那么为什么++的连接没有发生呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-02 16:49:19

你写过

代码语言:javascript
复制
safeDecodeJSONFile t f = do
  contents <- safeReadFile f
  tryRight $ ...

ExceptTExceptT实例一命中Left就会放弃,并准确地返回。所以tryRight ...从来没有发生过。您需要显式地处理Left案例,可能需要使用catchError

当我们在做的时候,仍然有一个问题。你写

代码语言:javascript
复制
safeReadFile :: FilePath -> ExceptT Text IO Text
safeReadFile p = (lift $ doesFileExist p) >>= bool (throwError "File does not exist") (lift $ pack <$> readFile p)

不幸的是,这不可靠。首先,不存在的文件只是读取失败的原因之一--可能是权限错误,网络文件系统的网络问题,如果文件不是常规文件,设备错误,等等。第二,其他人可以在检查文件存在和尝试读取文件的时间之间删除该文件。在尝试处理文件时,通常的建议是不要先检查。只需读取该文件并捕获使用catchControl.Exception或包装器中类似的异常。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57325619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档