Search code examples
stringhaskellincrementidentifier

Increment the numeric part of a string identifier in Haskell


I have this code (I'm a Haskell newbie).

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 ) )

Is it bad, average or good Haskell code? How can it be improved? Thanks.


Solution

  • import Data.List.Split
    

    Not being afraid of using non-base packages: This is good.

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

    Unneeded cases: this is not "bad" but "silly". Consider instead:

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

    If length s >= n then replicate (0 or negative) '0' == "" and this answer is the same as your otherwise case.

    -- 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 ) )
    

    Using indexing into lists (!!): this is bad because it is ugly and can fail (what if the list is shorter than you expected?).

    Over-use of parens: This is annoying

    How about:

    -- 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
    

    Over all very good work. Nicely done.