1

I'm not sure what I'm not handling. Suppose I have a function, that converts an integer to a string. Call it converter.

Now, to convert position integer to string, I just call converter. To convert a negative integer to string, I append - to the converter call.

This is my code:

converter :: Integer -> String
converter x
    | x == 0 = "0"
    | x == 1 = "1"
    | x == 2 = "2"
    | x == 3 = "3"
    | x == 4 = "4"
    | x == 5 = "5"
    | x == 6 = "6"
    | x == 7 = "7"
    | x == 8 = "8"
    | x == 9 = "9"
    | x > 9 = z
    where
    (a, b) = divMod x 10
    z = (converter a) ++ (converter b)

negOrPosConverter :: NegOrPosInteger -> String
negOrPosConverter (ActualInt x)
    | x >= 0 = converter x
    | x < 0 = "-" ++ (converter x)

When I run the code and try negOrPosConverter (ActualInt (-200)) I get this error:

"-*** Exception: theConverter.hs:(19,1)-(27,32): Non-exhaustive patterns in function converter

Any idea why?

SilentDev
  • 20,997
  • 28
  • 111
  • 214
  • Side note: you can replace the main body of `converter` with `if ((0<=x) && (x<10)) then show x else z`. `show` is a useful function from the main library which can convert most non-string values into strings. – bradrn May 25 '19 at 06:49
  • Remember to turn on warnings, so to discover these issues at compile time. If you have a list of guards `| condition = something | condition2 = something | ...` the last one should be `... | otherwise = something` to be sure of catching all the remaining cases. – chi May 25 '19 at 12:01

1 Answers1

6

The problem is that converter is only defined for nonnegative numbers. You prepend a "-" when it's negative, but you forgot to invert the actual number you pass to it. Try this instead:

negOrPosConverter :: NegOrPosInteger -> String
negOrPosConverter (ActualInt x)
    | x >= 0 = converter x
    | x < 0 = '-' : converter (-x)

Note converter (-x) instead of converter x.


Also, if this isn't just for practice, note that the show function already exists in Prelude to convert numbers (and lots of other things too) into strings.

  • Works. Just to clarify, when I do `"-" ++ (converter x)`, what exactly is it passing to `converter` then to make my code fail? I thought putting it in brackets `(converter x)` would just pass `x` to converter, and then add the `-`? Yup. Just to learn and get used to Haskell programming. – SilentDev May 25 '19 at 02:56
  • 2
    @user2719875 It does just pass `x` to converter. The problem is that `x` is negative in that case, and `converter` doesn't work on negative numbers. – Joseph Sible-Reinstate Monica May 25 '19 at 03:00
  • Ohhhhh. Got it. So what exactly does `x < 0 = '-' : converter (-x)` do? I haven't learned syntax of `:` yet. I'm guessing it remove the `-` temporarily? Thanks in advance. – SilentDev May 25 '19 at 03:02
  • 1
    @user2719875 `'-' :` does the exact same thing as `"-" ++`. `:` just lets you add one element at a time more efficiently than `++`. – Joseph Sible-Reinstate Monica May 25 '19 at 03:04
  • 1
    Ok, so `converter (-x)` is basically what solves the problem, right? The line `x < 0 = '-' : converter (-x)` says, if `x < 0` i.e. a negative integer, then pass it as an argument to `converter` After negating it (`converter (-x)`), to make it positive when passing it to `converter`. Is my understanding right? – SilentDev May 25 '19 at 03:07
  • 1
    @user2719875 If you look at the definition of `(++)`, you'll find the relevant case to be `(x:xs) ++ ys = x : xs ++ ys`, and `"-"` is the same thing as `'-':[]`, so `"-" ++ converter x` is equivalent to `'-' : converter x`, which prepends a `'-'` to the result of `converter x`. – Rein Henrichs May 25 '19 at 17:55