在Haskell中插入一行try-catch块

时间:2014-10-31 22:46:16

标签: exception haskell exception-handling try-catch

为了处理返回Nothing的情况,我想添加一个非常简单的try-catch块,对此类实例中的表达式没有刺激。

instance QWho (Argument -> Predicate -> Predicate) Predicate where
            qWho verb predicate =
                let 
                arg = head (arguments predicate)
                factsByArg = getFactsByArg arg
                in if null factsByArg then error ("The argument <" ++ getValue arg ++ "> does not exist in any fact.") 
                else
                    let locaPreds = filter (\x -> x == (verb (fromJust (getAgentByType x [HUMN])) predicate)) factsByArg
                    in if null locaPreds then error ("No such fact exists.")
                    else
                        let locaArgs = map (\x -> getAgent x) locaPreds
                        in map getValue locaArgs

违规表达是(\x -> x == (verb (fromJust (getAgentByType x [HUMN])) predicate))。除非fromJust返回Nothing,否则此方法有效。理想情况下,我想我可以做这样的事情:

(\x -> try (x == (verb (fromJust (getAgentByType x [HUMN]))))

但这不起作用(它会使用像Java这样的语言,尽管我最后需要捕获。)

有很多资源试图解释如何在Haskell中执行try-catch块。我发现的那些没有提供我正在寻找的单一快速修复(即没有重大的代码重组)。是否有快速修复可以忽略返回Nothing的情况,而不是由于Maybe.fromJust异常导致程序退出?

相关来源:

(1)http://drunkcoding.tumblr.com/post/692076953/catching-exceptions-in-haskell

1 个答案:

答案 0 :(得分:1)

您不能在Haskell中使用trycatch,除了IO操作,这些操作不能在纯代码中使用。但是 是一个简单的快速修复:

let locaPreds = filter (\x -> Just x == fmap (\agent -> verb agent predicate)
                                             (getAgentByType x [HUMN]))
                    factsByArg

MaybeFunctor类型类的成员,这意味着它是许多数据类型之一,您可以使用fmap来应用函数什么是“内部”它。因此,您可以将 内的 out 推送到。

如果Maybe的结果为getAgentByType x [HUMN],则该函数将应用于Just agent,结果为agent,您可以将其与{{1}进行比较}。 如果有Just (verb agent predicate),则结果仍为Just x,不等于Nothing,因此测试失败。

Nothing函数允许您切换函数参数的顺序,因此您也可以将内部lambda表达式写为Just x