haskell - 如何在 Haskell 中实现产生 Maybe String 的 safeReadFile 函数
问题描述
我正在尝试loadFile
在 Haskell 中实现一个安全函数,该函数捕获任何异常并产生 aMaybe String
但以下实现无法编译
import System.IO (readFile)
import Control.Exception (catch, IOException)
-- readFile :: FilePath -> IO String
-- this compiles good
safeReadFile :: FilePath -> IO (Either IOException String)
safeReadFile p =
(Right <$> readFile p) `catch`
(\e -> pure $ Left e)
-- this does not!
safeReadFile' :: FilePath -> IO (Maybe String)
safeReadFile' p =
(Just <$> readFile p) `catch`
(\e -> pure Nothing)
谁能解释一下为什么 GCH 会提出以下问题?
Ambiguous type variable ‘e0’ arising from a use of ‘catch’
prevents the constraint ‘(GHC.Exception.Exception
e0)’ from being solved.
Probable fix: use a type annotation to specify what ‘e0’ should be.
These potential instances exist:
instance GHC.Exception.Exception IOException
-- Defined in ‘GHC.IO.Exception’
...plus 20 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
如何在e
变量上应用必要的类型注释?Haskell 文档没有提供任何线索:-(
解决方案
您必须指定要捕获的异常类型。safeLoadFile
明确提到IOException
,而safeLoadFile'
没有。
试试这个:
safeLoadFile' :: FilePath -> IO (Maybe String)
safeLoadFile' p =
(Just <$> loadFile p) `catch`
((\e -> pure Nothing) :: IOException -> IO (Maybe String))
或者找到一些类似的方法来注释变量的类型e
。例如(\ (e :: IOException) -> ...)
,如果您打开ScopedTypeVariables
.
还有另一种选择:
safeLoadFile' :: FilePath -> IO (Maybe String)
safeLoadFile' p = (Just <$> loadFile p) `catch` handler
where
handler :: IOException -> IO (Maybe String)
handler _ = pure Nothing
推荐阅读
- networking - 网络图悬停以隐藏链接标签
- sql - 如何将 DATETIME 类型用于变量?
- go - 如何强制释放(垃圾收集)切片?
- python - 插入操作中的 sqlite3 的 RBDMS 错误..回滚
- python - 在植绒游戏python中添加障碍物
- django - Django/Docker/Postgresql - psycopg2 错误
- flutter - Flutter - 如何在Overlay下传递滚动事件?
- java - 我的机会系统有什么问题?
- typescript - gRPC-web 打字稿如何从长转换为数字
- listbox - MS Access:如何构建列表框,其中一个下拉字段的选择影响填充另一个下拉字段?