在Haskell标准库的帮助下重构这种虚拟代码的最佳方法是什么?

时间:2018-02-17 19:35:09

标签: haskell refactoring

我目前正在处理用Haskell编写的非常脏的项目。 它包含许多代码,如:

try_parse_parameters (p:ps) kvps options = 
        let maybeKvp = try_parse_kvp p 
        in
          if isJust maybeKvp 
            then try_parse_parameters ps ((fromJust maybeKvp) : kvps) options
            else 
              let maybeOption = try_parse_option p
              in 
                if isJust maybeOption
                  then try_parse_parameters ps kvps ((fromJust maybeOption) : options)
                  else try_parse_parameters ps kvps options

因此,我的问题是:是否有一些标准方法来处理这种情况?

2 个答案:

答案 0 :(得分:4)

是的,您正在寻找的是模式匹配,如果没有它,您就无法真正编写haskell。这是您的代码最直接的改编:

try_parse_parameters (p:ps) kvps options = 
    case try_parse_kvp p of
      Just kvp -> try_parse_parameters ps (kvp : kvps) options
      Nothing -> 
        case try_parse_option p of
          Just o -> try_parse_parameters ps kvps (o : options)
          Nothing -> try_parse_parameters ps kvps options

从这里可以看到很多东西,无论是现在还是以后,你都会了解更多的东西:

  • 我真的建议使用CamelCase,它是标准的但也更具可读性,因为你可以很容易地将功能与其参数区分开来
  • 你在列表上做 fold 。您可以使用foldr来计算递归,并让读取您的代码的人更清楚它做了什么(以及它不能做什么;即使其更容易推理)
  • 添加类型签名,处理空列表案例,可能还有其他问题
  • 您可能会发现Alternative类很有帮助,或者如果您希望如果任何解析完全失败导致整个计算失败,则可能会使用monadic折叠

答案 1 :(得分:4)

您还可以使用模式匹配处理多个案例,避免使用pyramid of doom

try_parse_parameters (p:ps) kvps options = 
    case (try_parse_kvp p, try_parse_option p) of
      (Just k, _)       -> try_parse_parameters ps (k : kvps) options
      (Nothing, Just o) -> try_parse_parameters ps kvps (o : options)
      (Nothing, Nothing)-> try_parse_parameters ps kvps options