在haskell中的复杂函数中将int转换为int

时间:2017-02-28 19:00:32

标签: 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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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
              ]

假设我做了那个重构......

答案 2 :(得分: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