为了处理返回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
答案 0 :(得分:1)
您不能在Haskell中使用try
和catch
,除了IO
操作,这些操作不能在纯代码中使用。但是 是一个简单的快速修复:
let locaPreds = filter (\x -> Just x == fmap (\agent -> verb agent predicate)
(getAgentByType x [HUMN]))
factsByArg
Maybe
是Functor
类型类的成员,这意味着它是许多数据类型之一,您可以使用fmap
来应用函数什么是“内部”它。因此,您可以将 内的 out 推送到。
如果Maybe
的结果为getAgentByType x [HUMN]
,则该函数将应用于Just agent
,结果为agent
,您可以将其与{{1}进行比较}。
如果有Just (verb agent predicate)
,则结果仍为Just x
,不等于Nothing
,因此测试失败。
Nothing
函数允许您切换函数参数的顺序,因此您也可以将内部lambda表达式写为Just x
。