2014-10-31 98 views
1

爲了處理返回Nothing的情況,我想在這個類實例的表達式中添加一個非刺激的非常簡單的try-catch塊。在Haskell中插入一行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。理想情況下我想我可以做這樣的事情:(它會像Java語言,雖然我在最後需要一個抓)

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

但不起作用

有有很多資源試圖解釋如何在Haskell中做一個try-catch塊。我發現的那些不提供我正在尋找的單個快速修復(即沒有對代碼進行重大重構)。是否有快速修復來忽略返回Nothing的情況,而不是由於Maybe.fromJust異常導致程序退出?

一個相關的源:

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

+2

爲什麼在使用'fromJust'之前不檢查'是否...'?或者甚至更好,使用patter匹配和'case'來處理'Nothing'和'Just x'的情況? 'fromJust'部分函數可以說是破壞/消除'Maybe a'值的最糟糕的方式。 TLDR:不要尋找處理異常的方法,而是避免它! – chi 2014-10-31 23:08:02

+0

確保你的'then' /'else's比其相應的'if'更加縮進。當let'聲明比'let'更深時,'let'聲明的內容看起來更好看,但這只是一種風格。 – genisage 2014-10-31 23:55:06

+0

我不確定如何在lambda表達式中放置case語句。看到這個線程:http://stackoverflow.com/questions/3416475/haskell-guards-on-lambda-functions @genisage是否有一種方法來使用parens所有的範圍,例如像Lisp一樣?我使用的編輯器並不真正適用於縮進。 – user3898238 2014-11-01 01:13:01

回答

1

不能在Haskell使用trycatch除非IO操作,可以不是純碼內使用。然而,有一個簡單的快速修復:

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

MaybeFunctor類型類的成員,這意味着它是許多數據類型的,你可以用fmap到功能應用到什麼是一個「在裏面。所以不要拿東西Maybe,你可以把你的支票放在裏面吧。

如果從getAgentByType x [HUMN]結果是Just agent,則該函數將被應用到agent,給人的結果Just (verb agent predicate),你可以比較Just x。 如果有Nothing,結果仍然是Nothing,這不等於Just x,所以測試失敗。

flip函數允許您切換函數參數的順序,因此您還可以編寫內部lambda表達式,其縮寫爲flip verb predicate