Haskell 我无法通过尝试获得 ReadFile 异常

Haskell I can not get exception ReadFile with try

我有一个函数 "management" 检查参数和 return 一个 Maybe (String):

当我获取一个文件并检查该文件是否存在时,我的问题就来了。

Couldn't match expected type ‘Maybe String’ with actual type ‘IO (Either e0 a2)’

managagment :: [String] -> Maybe (String)
managagment [] = Nothing
managagment ["-h"] = Just (help)
managagment [file] = try $ readFile file >>= \result -> case result of
                                                        Left e -> Nothing
                                                        Right content -> Just (content)

有几个问题

函数应用($)的优先级低于绑定(>>=

你说:

try $ readFile file >>= \res...

这意味着

try ( readFile file >>= \res... )

但你想要:

try ( readFile file ) >>= \res...

IO (Maybe a)Maybe a 是不同的

您有一个使用 IO 的函数(通过 readFiletry),但许多情况下 return 没有 IO 结果(NothingJust content).

解决方案:Return 通过 return Nothingpure Nothing 将值提升到 IO monad。

异常类型不明确

try函数可以捕获任何异常类型,看签名就知道了:

try :: Exception e => IO a -> IO (Either e a)

当你完全忽略异常时,你让类型检查器没有任何信息来决定 e 应该是什么。在这些情况下,显式类型签名很有用,例如:

  Left (e::SomeException) -> pure Nothing

managagment部分

managagment ["a","b"] 未定义,任何长度超过一的输入列表也是如此。考虑以下的最终方程式定义:

managagment _ = managagment ["-h"]

或更直接:

managagment _ = pure $ Just help

样式和其他注释

  • managagment 应该是 management
  • Just (foo)一般是Just foo
  • help 不是 return 字符串的函数。它是一个字符串类型的值。
  • 示例不完整,缺少导入和 help

固定代码

改为考虑:

#!/usr/bin/env cabal
{- cabal:
    build-depends: base
-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE LambdaCase          #-}
import Control.Exception (try, SomeException)

main :: IO ()
main = print =<< management []

help :: String
help = "so helpful"

management :: [String] -> IO (Maybe String)
management [] = pure Nothing
management ["-h"] = pure $ Just help
management [file] =
    try (readFile file) >>=
      \case
         Left (e::SomeException) -> pure Nothing
         Right content -> pure $ Just content
management _ = pure $ Just help

并这样测试:

% chmod +x x.hs
% ./x.hs