gpt4 book ai didi

haskell - 由于使用 ‘a0’ 而产生的模糊类型变量 ‘Ex.catch’

转载 作者:行者123 更新时间:2023-12-04 06:58:15 24 4
gpt4 key购买 nike

我一直在摆弄 Haskell,试图理解错误处理。在这样做的同时,我试图掌握如何阅读和理解 GHC 的输出,以便更好地调试类型错误。

我编写了以下测试:

import System.Environment
import qualified Control.Exception as Ex

getNum :: Int -> Int
getNum i = (!!) [1,2,3,4] i

outNum :: Int -> IO()
outNum i = Ex.catch (putStrLn(show (getNum i))) (\err -> putStrLn (show err))

main = do
args <- getArgs
outNum 3

这会引发以下错误:

Ambiguous type variable ‘a0’ arising from a use of ‘Ex.catch’ prevents the constraint ‘(Ex.Exception a0)’ from being solved.

查看涉及函数的定义:

catch :: IO a -> (IOError -> IO a) -> IO a
putStrLn :: String -> IO ()
show :: Show a => a -> String
error :: [Char] -> a

我正在看这个并且在想,a 的类型必须是 ()(单位类型)。我误解了什么,我应该如何修改我的示例以使其捕获异常并显示错误?

最佳答案

GHC 不知道为什么要捕获异常类型。

例如,此版本的 outNum 将捕获任何 IOException:

outNum :: Int -> IO()
outNum i = Ex.catch (putStrLn(show (getNum i)))
(\err -> putStrLn (show (err :: Ex.IOException)))

您可以使用 Ex.SomeException 捕获所有异常。但是,请参阅关于在 Control.Exception docs 中执行此操作的评论

要捕获几种不同类型的异常,请参阅 catches function

更新

另一种表示您感兴趣的异常类型的方法是将处理程序定义为命名函数并提供“正常”类型签名:

outNum i = Ex.catch (putStrLn (show (getNum i))
handler
where handler :: Ex.IOException -> IO ()
handler err = putStrLn $ "caught: " ++ show err

而且您经常会看到 catch 被写成一个中缀运算符:

outNum i = putStrLn (show (getNum i)) `catch` handler

最后,您可以使用 ScopedTypeVariables 放置类型注释关于 lambda 的参数:

{-# LANGUAGE ScopedTypeVariables #-}

outNum i = putStrLn ...
`catch` (\(err :: Ex.SomeException) -> putStrLn ("caught: " ++ show err))

关于haskell - 由于使用 ‘a0’ 而产生的模糊类型变量 ‘Ex.catch’,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39157822/

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