Overwriting previous functions - haskell

I have a function, which contains the first 101 characters:
characters :: [String]
characters = [[chr i] |i<-[0..100]]
And what I need to do is to make the next function append to this one permanently, so far I have tried something like this, but this doesn't keep the result.
append :: [String] -> String -> String -> [String]
append characters xs ys = characters ++ [(take 2 (xs++ys))]
So pretty much what I need is to be able to continuously expand my characters function with the append function, and not lose the results.
Thanks for the answers.

Values are immutable in Haskell, so
characters ++ somethingElse
produces a new list, containing a copy of characters at the front, characters itself remains unchanged.
So, as stated, your task is impossible. What are the actual requirements?

I don't know, what you're trying to do with your example. But to answer just your subject, you can import with the hiding-flag and write your own version of a function, like:
import Data.Text hiding (append)
HTH

Related

Implementing rotors

How can I pattern match 2 strings in Haskell? Like let's say I have one string which is all the alphabets "ABCDEFGHIJKLMNOPQRSTUVWXYZ" and another string "EKMFLGDQVZNTOWYHXUSPAIBRCJ". It's like a ciphering thing, where I want to pattern match both these strings so that when I type HELLO in plain text using the normal alphabets, I get "QLTTY".
Let's save these strings so we have some convenient names.
a = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
b = "EKMFLGDQVZNTOWYHXUSPAIBRCJ"
Now if you zip them together you get a lookup table.
ghci> cypher = zip a b
ghci> cypher
[('A','E'),('B','K'),('C','M'),('D','F'),('E','L'),('F','G'),('G','D'),('H','Q'),('I','V'),('J','Z'),('K','N'),('L','T'),('M','O'),('N','W'),('O','Y'),('P','H'),('Q','X'),('R','U'),('S','S'),('T','P'),('U','A'),('V','I'),('W','B'),('X','R'),('Y','C'),('Z','J')]
You now simply need to map your string to a lookup on this cypher.
map (\ch -> ...) "HELLO"
This should give you a nudge in the right direction.

Writing newlines to files

How can I write a string that contains newlines ("\n") to a file so that each string is on a new line in the file?
I have an accumulator function that iterates over some data and incrementally constructs a string (that contains information) for each element of the data. I don't want to write to the file every step so I'm appending the strings in each step. I do this so I can write the string in one time and limit the amount of IO.
Adding a newline to the string via str ++ "\n" doesn't work, hPrint h str will just print "\n" instead of starting on a new line.
I've tried accumulating a list of strings, instead of one big string, and iterating over the list and printing each string via hPrint. This works for the newlines but it also prints the quotation marks around each string on every line.
Don't use hPrint to write the strings to the file. Just like regular print it outputs the result of show, which produces a debugging-friendly version of the string with control characters and line endings escaped (and the surrounding quotes).
Use hPutStr or hPutStrLn instead. They will write the string to the file as-is (well, the latter adds a newline at the end).
The probably idiomatic solution to what you try to do is to simply aggregate the resulting strings in a list. Then, use the unlines prelude function which has the signature unlines :: [String] -> String and does your \n business for you.
Then, writing the string to disk can be done with help of writeFile which has the signature: writeFile :: FilePath -> String -> IO ().
Haskell is lazy. As such, it sometimes helps to think of Haskell lists as enumerators (C# like IEnumerable). This means here, that trying to compute line wise, then build the string manually and write it line by line is not really necessary. Just as readFile works lazily, so then does e.g. lines. In other words, you gain nothing if you try to "optimize" code which looks in its genuine form similar to this:
main = do
input <- readFile "infile"
writeFile "outfile" ((unlines . process) (lines input))
where
process inputLines = -- whatever you do

Backslash in string changing output

I am currently trying to implement a method that counts the number of characters and digits in a string. However if I use a string that contains the '\' character I am getting strange results. I am guessing it's because the backslash character is an escape character.
Here is the method:
import Data.Char
countLettersAndDigits :: String -> Int
countLettersAndDigits [] = 0
countLettersAndDigits (x:xs) = if isDigit x == True || isLetter x == True
then 1 + countLettersAndDigits xs
else countLettersAndDigits xs
Here is a set of inputs with their respective results:
"1234fd" -> 6 (Doesn't contain '\')
"1234f\d" -> lexical error in string/character literal at character
'd'
"1234\fd" -> 5
"123\4fd" -> 5
"12\34fd" -> 4
"1\234fd" -> 4
"\1234fd" -> 3
I find it strange that, for example, "1234\fd" and "123\4fd" both give 5 as a result.
Any help explaining why this maybe the case and also how to get around this problem? would be great!
Cheers.
Edit
I forgot to mention that the string that I used above was just an example I was playing with. The actual string that is causing a problem is being generated by Quick Check. The string was "\178". So I require a way to be able to handle this case in my code when their is only one backslash and the string is being generated for me. Cheers.
You are correct that \ is Haskell's escape character. If you print out the generated strings, the answer may be more obvious:
main = mapM_ putStrLn [ "1234fd"
, "1234\fd"
, "123\4fd"
, "12\34fd"
, "1\234fd"
, "\1234fd"
]
yields...
1234fd
1234d
123fd
12"fd
1êfd
Ӓfd
If you actually intended on including a backslash character in your string, you need to double it up: "\\" will result in a single \ being printed.
You can read up on escape sequences here.

Creating an array of possible string variations

I'm trying to figure out how I would create variations of a string, by replacing one character at a time in the string with a different character from another array.
For example:
variations = "abc"
getVariations "xyz" variations
Should return:
["xbc", "ybc", "zbc", "axc", "ayc", "azc", "abx", "aby", "abz"]
I'm not quite sure how to go about this. I tried iterating through the string, and then using list comprehension to add the possible characters but I end up losing characters.
[c ++ xs | c <- splitOn "" variations]
Where xs is the tail of the string.
Would someone be able to point me in the right direction please?
Recursively you can define getVariations replacements input
if input is empty, the result is ...
if input is (a:as), combine the results of:
replacing a with a character from replacements
keeping a the same and performing getVariations on as
This means the definition of getVariations could look ike:
getVariations replacements [] = ...
getVariations replacements (a:as) = ...#1... ++ ...#2...
It might also help to decide what the type of getVariations is:
getVariations :: String -> String -> ???

Haskell - Import text file to list type

I am beginner in haskell. I have a .txt file in the following format:
Company A, 100, 1000
I need to import each row to a list of one type:
type GerCred = [(String, Int, Int)]
How do I do that?
Update
This is what I have tried so far:
type GerCred = [(String,Int,Int)]
type GerCarb = [(String,Int)]
readGerCredList :: File -> IO GerCred
readGerCredList fname = do contents <- readFile fname return(read contents)
Break the problem down into bits.
First, figure out how to read the file into a single big string (hint, look for something that returns "IO String")
Then figure out how to take that string and split it into lines (hint: lines).
Then figure out how to take each line and split it into fields (hint: span, stripPrefix)
Then figure out how to convert each field into the type you need (hint: read).
Then figure out how to put it all together (hint: map)
Don't forget that a String is just a [Char].
Paul.

Resources