2017-02-28 40 views
1

我有這樣的功能:轉換也許詮釋在一個複雜的函數爲int在Haskell

to_ref :: Idx -> Idx -> Idx -> Idx -> Mat El -> Mat El 
to_ref cb ce rb re m 
    | cb <= ce && (find_non_null_row cb rb re m) == Nothing = (to_ref (cb+1) ce rb re m) 
    | cb <= ce && (find_non_null_row cb rb re m) /= Nothing = (elim_all cb rb re (find_non_null_row cb rb re m) m) : (to_ref (cb+1) ce rb re m) 
    | otherwise = m 

(elim_all cb rb re (find_non_null_row cb rb re m) m) : (to_ref (cb+1) ce rb re m)(find_non_null_row cb rb re m)返回Maybe Int類型值,但我需要它作爲Int類型使我的工作。

我已經檢查了這個帖子,http://stackoverflow.com/questions/8905272/convert-maybe-int-to-int-in-haskell,但我無法解決我的問題。

如何以最有效的方式將其轉換爲Int

+2

可能的複製(http://stackoverflow.com/questions/8905272/convert-maybe-int [轉換也許詮釋在Haskell到INT] to-int-in-haskell) – jkeuhlen

回答

3

只需使用模式匹配。在這裏,我將cbce的比較顛倒過來,以避免更復雜的情況。

to_ref cb ce _ _ m | cb > ce = m 
-- If we get to this case, we know cb < ce 
to_ref cb ce rb re m = let ref = to_ref (cb+1) ce rb re m 
          row = find_non_null_row cb rb re m 
         in case row of 
          Nothing -> ref 
          Just x -> elim_all cb rb re x m : ref 

您也可以使用maybe功能,如果你不喜歡case表達。

to_ref cb ce rb re m = let ref = to_ref (cb+1) ce rb re m 
          row_f x = elim_all cb rb re x m : ref 
          row = find_non_null_row cb rb re m 
         in maybe ref row_f row 
+0

Prelude。!!:index too large – yusuf

+2

由於'!!'在這段代碼中沒有出現,所以我幾乎沒有關於該怎麼做的想法。有可能您的原始代碼應該使用'cb = ce'? – chepner

1

我的風格是使用PatternGuards

to_ref :: Idx -> Idx -> Idx -> Idx -> Mat El -> Mat El 
to_ref cb ce rb re m 
    | cb <= ce, Just row <- find_non_null_row cb rb re m 
     = elim_all cb rb re row m : to_ref (cb+1) ce rb re m 
    | cb <= ce 
     = to_ref (cb+1) ce rb re m 
    | otherwise = m 

列表理解實際上似乎適合很好

to_ref cb0 ce rb re m = newItems ++ m 
    where 
    newItems = [ elim_all cb rb re row m 
       | cb <- [cb0..ce] 
       , Just row <- find_non_null_row cb rb re m 
       ] 

假設我這樣做,重構正確的...

1

您目前使用的是可以分離的三個後衛分成兩個警衛和一個案例表達(解開Maybe)。我也抽象掉一些重複計算的用的let

to_ref :: Idx -> Idx -> Idx -> Idx -> Mat El -> Mat El 
to_ref cb ce rb re m 
    | cb <= ce = 
     let 
      ref = to_ref (cb + 1) ce rb re m 
      row = find_non_null_row cb rb re m 
     in case row of 
      Nothing -> ref 
      Just x -> elim_all cb rb re x m : ref 
    | otherwise = m