【问题标题】:Increment the numeric part of a string identifier in Haskell在 Haskell 中增加字符串标识符的数字部分
【发布时间】:2013-08-27 10:46:09
【问题描述】:

我有这个代码(我是 Haskell 新手)。

import Data.List.Split

padL :: Int -> String -> String
padL n s
    | length s < n = replicate (n - length s) '0' ++ s
    | otherwise = s

strInc :: String -> String -> String
strInc sep str = 
        let strarr = splitOn sep str
            zprefix = strarr !! 0
            znumber = strarr !! 1
        in zprefix ++ sep ++ padL ( length (znumber) ) ( show ( read ( znumber ) + 1 ) )

Haskell 代码是差的、一般的还是好的?如何改进? 谢谢。

【问题讨论】:

  • 我认为 Stackoverflow 不适合问这个问题。该网站是关于问题的,而不是代码审查。对于代码审查,有codereview.stackexchange.com
  • 我问的是我可能不知道的惯用 Haskell。已经有一个接受并回答了“我应该如何重构这个 Haskell...”的问题,类似于我的问题。如果有帮助,我可以在没有我的代码的情况下重新制定,标题对我的问题是不言自明的。
  • 如果可能的话,单独维护标识符的数字部分,稍后再添加字符串部分。拥有String -&gt; String 类型的数字增量函数似乎令人不快。如果您可以使用自定义读取和显示将您的号码包装在 newtype 中以实现您的最终结果,那就更好了。 (不知道你用这个做什么,这就是为什么我不确定。)
  • 这是一个学习练习。这是“你如何用那种语言做到这一点”的一部分。我在 Haskell 中提出了上述代码,但我想对我自己的 Haskell 开发进行审查。

标签: string haskell increment identifier


【解决方案1】:
import Data.List.Split

不怕使用非基础包:这很好。

-- Original code
padL :: Int -> String -> String
padL n s
    | length s < n = replicate (n - length s) '0' ++ s
    | otherwise = s

不需要的情况:这不是“坏”而是“愚蠢”。请考虑:

-- New code
padL n s = replicate (n - length s) '0' ++ s

如果 length s &gt;= nreplicate (0 or negative) '0' == "" 并且此答案与您的其他情况相同。

-- Original code
strInc :: String -> String -> String
strInc sep str = 
        let strarr = splitOn sep str
            zprefix = strarr !! 0
            znumber = strarr !! 1
        in zprefix ++ sep ++ padL ( length (znumber) ) ( show ( read ( znumber ) + 1 ) )

在列表中使用索引 (!!):这很糟糕,因为它很难看并且可能会失败(如果列表比您预期的要短怎么办?)。

过度使用括号:这很烦人

怎么样:

-- New code
strInc :: String -> String -> String
strInc sep str =
    case splitOn sep str of
      (zprefix:znumber:_) -> zprefix ++ sep ++ padL (length znumber) (show (read znumber + 1))
      _ -> "" -- some error value

总的来说,工作非常好。做得很好。

【讨论】:

  • 所以复制适用于负值。好东西。我真的很喜欢你的 strInc 函数!有一件事我要问,为什么 _ 作为案例的第一个测试用例的尾部?谢谢!
  • 啊,所以 _ 只是模式匹配中未命名变量的表示法,zprefix:znumber:restOfList == zprefix:znumber:_ 请注意,这与 [zprefix,znumber] 略有不同,后者仅匹配两个元素的列表(而不是两个或更多元素)。
  • 我明白了,如果我使用多个分隔符,它只会管理第二个元素,并松散尾部。顺便问一下,我如何处理 znumber 不转换为数字的情况,即 znumber = 00001a?谢谢。
  • 您可以使用 readMaybe 和模式匹配或使用maybe 函数。
猜你喜欢
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 1970-01-01
相关资源
最近更新 更多