Home > Software engineering >  Convert string into new data structure and back into string
Convert string into new data structure and back into string

Time:11-29

I'm pretty new to Haskell so apologies if this sounds a bit dumb to ask... I'm trying to create a new data structure BigNumber with 2 arguments: a char with ' ' Or '-' to differentiate between positive and negative numbers and a list of the number's digits. And use this in 2 functions: scanner that converts a string into a BigNumber and output that converts a BigNumber into a string. This is what I have so far:

data BigNumber = Char [Integer]
   
-- Verifies if the number is positive or negative and returns its correspondent char 
scanner_Sign :: Char -> Char
scanner_Sign s = if s == '-' then '-' else ' '

-- Converts string into list of digits (without signal)                
scanner_Numbers :: (Char, String) -> [Integer]
scanner_Numbers (sign, s) 
                | sign == ' ' = map (read . (:"")) s :: [Integer]
                | sign == '-' = map (read . (:"")) (tail s) :: [Integer]

scanner :: String -> BigNumber
scanner = scanner_Numbers (s, n)
          where scanner_Sign (head s)

output :: BigNumber -> String
output (sign, numbers)
       | sign == ' ' = show numbers
       | sign == '-' = - (show numbers)
       where (BigNumber (sign, numbers))

Both the aux functions for scanner are working but I don't know how to use them in the main. And I'm still clueless regarding the output function... What I am doing wrong?

CodePudding user response:

I'm trying to create a new data structure BigNumber with 2 arguments:

This data BigNumber = Char [Integer] creates a new datatype with a Constructor named Char and only one argument. So either create a new datatype like this:

data BigNumber = BigNumber Char [Integer]

and adapt your functions accordingly, or you can mostly keep your output function with

type BigNumber = (Char, [Integer])

By the way, Integers in haskell already support arbitrary large (and negative) numbers. You might use Int instead.

Both the aux functions for scanner are working

"working" as in "compiling"? It seems you want

scanner_Numbers ('-', "1234") == [2,3,4]

This drops the "1". Hm, because you want to repeat the first character, i.e. call scanner_Numbers ('-', "-567"). This is unnecessary. You can just do

 scanner ('-':s) = BigNumber '-' that-map-read-stuff-with-s
 scanner s       = BigNumber ' ' that-map-read-stuff-with-s

Your syntax for where-clauses is off. You need definitions there, i.e. they have a = sign just like the top level functions.

regarding output:

   | sign == '-' = - (show numbers)

Does not compile. show has a signature, roughly show :: whatever -> String. So it returns a String and you try to negate a String. -is not an operation on Strings! Fortunately, : is an operation on Strings, so try to put a character representing your minus there. Seriously, try to understand what I just wrote before unmasking the spoiler.

| sign == '-' = '-' : (show numbers)

Then you will find out show numbers does not produce the pretty output you want. Hint: something like you did when converting from String to BigNumber, just the other way round.

  • Related