gpt4 book ai didi

Haskell:在异常情况下不返回任何内容

转载 作者:行者123 更新时间:2023-12-05 08:23:46 25 4
gpt4 key购买 nike

{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables #-}

import Data.Typeable
import Control.Exception

data EmptyListException = EmptyListException
deriving (Show, Typeable)
instance Exception EmptyListException

myHead :: [a] -> a
myHead [] = throw EmptyListException
myHead (x:_) = x

mySafeHead :: [a] -> IO (Maybe a)
mySafeHead xs = (return (Just (myHead xs)))
`catch`
(\(ex::EmptyListException) -> return Nothing)

如果有的话,我想返回 xs 的第一个元素。否则我想返回“Nothing”,但它返回包裹在“Just”中的异常。这是为什么?P.S.:我必须在 mySaveHead 中使用 myHead

最佳答案

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

λ mySafeHead []
Just *** Exception: EmptyListException

我理解您为什么将其描述为“它返回包含在“Just”中的异常。”,但实际情况并非如此。

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

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

然后,在 ghci 中,thunk 在尝试打印值时最终被强制执行,并引发异常。由于我们现在完全超出了 catch 语句的范围,因此它不适用,并且异常一直到终端,在那里它中断了输出的打印。

解决此问题的简单方法是在退出 catch 语句之前使用 seq 强制计算 myHead xs:

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

seq 接受两个参数 - 它返回第二个参数,但仅在将第一个参数强制为 Weak Head Normal Form (WHNF) 之后,即在找出最外层的构造函数之后。这会强制 x 足以引发 EmptyListException,因此 catch 可以执行它的操作:

λ mySafeHead' []
Nothing

关于Haskell:在异常情况下不返回任何内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34387424/

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