当前位置:  开发笔记 > 编程语言 > 正文

Haskell:如果发生异常,则不返回任何内容

如何解决《Haskell:如果发生异常,则不返回任何内容》经验,为你挑选了2个好方法。

所以当我运行你的代码时,这就是我所看到的

? mySafeHead []
Just *** Exception: EmptyListException

我明白为什么你会把它描述为"它返回包含在"Just"中的Exception.",但这实际上不是正在发生的事情.

Haskell是非严格的,因此它推迟计算直到需要一个值.

在未检查mySafeHead的值中myHead xs,因此不进行评估.相反,该值的计算保留为thunk,它被包装Just并返回.

然后,在ghci尝试打印该值时,最终强制该thunk,并引发异常.由于我们现在已经超出了catch语句的范围,因此它不适用,并且异常使它一直到终端,它终止输出的打印.

解决这个问题的简单方法是在退出语句之前使用seq强制评估:myHead xscatch

mySafeHead' :: [a] -> IO (Maybe a)                             
mySafeHead' xs = (let x = myHead xs in x `seq` return (Just x))
                `catch`                                        
                (\(_::EmptyListException) -> return Nothing)   

seq有两个参数 - 它返回第二个参数,但只有在强制第一个到弱头范式(WHNF)之后,也就是在找出最外面的构造函数之后.这有x足够的力量EmptyListException来提升,所以catch可以做到这一点:

? mySafeHead' []
Nothing


Shoe.. 5

您可以evaluate在执行纯计算时用于捕获异常:

mySafeHead :: [a] -> IO (Maybe a)
mySafeHead xs = mySafeHead' xs `catch` handler
    where  
        mySafeHead' :: [a] -> IO (Maybe a)
        mySafeHead' ls = do
            x <- evaluate $ myHead ls
            return $ Just x
        handler :: EmptyListException -> IO (Maybe a)
        handler ex = return Nothing

Live demo



1> rampion..:

所以当我运行你的代码时,这就是我所看到的

? mySafeHead []
Just *** Exception: EmptyListException

我明白为什么你会把它描述为"它返回包含在"Just"中的Exception.",但这实际上不是正在发生的事情.

Haskell是非严格的,因此它推迟计算直到需要一个值.

在未检查mySafeHead的值中myHead xs,因此不进行评估.相反,该值的计算保留为thunk,它被包装Just并返回.

然后,在ghci尝试打印该值时,最终强制该thunk,并引发异常.由于我们现在已经超出了catch语句的范围,因此它不适用,并且异常使它一直到终端,它终止输出的打印.

解决这个问题的简单方法是在退出语句之前使用seq强制评估:myHead xscatch

mySafeHead' :: [a] -> IO (Maybe a)                             
mySafeHead' xs = (let x = myHead xs in x `seq` return (Just x))
                `catch`                                        
                (\(_::EmptyListException) -> return Nothing)   

seq有两个参数 - 它返回第二个参数,但只有在强制第一个到弱头范式(WHNF)之后,也就是在找出最外面的构造函数之后.这有x足够的力量EmptyListException来提升,所以catch可以做到这一点:

? mySafeHead' []
Nothing



2> Shoe..:

您可以evaluate在执行纯计算时用于捕获异常:

mySafeHead :: [a] -> IO (Maybe a)
mySafeHead xs = mySafeHead' xs `catch` handler
    where  
        mySafeHead' :: [a] -> IO (Maybe a)
        mySafeHead' ls = do
            x <- evaluate $ myHead ls
            return $ Just x
        handler :: EmptyListException -> IO (Maybe a)
        handler ex = return Nothing

Live demo


@immibis无论如何都要在IO中捕获异常...所以你不会丢失任何东西.
推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有