我有这样一个功能:
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
?
答案 0 :(得分:3)
只需使用模式匹配。在这里,我颠倒了cb
和ce
的比较,以便在更复杂的情况下解决这个问题。
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