I have this code and instead of it printing out "\n", I want it to put the next string on a new line, but cannot seem to figure it out. Any pointers?
onSeparateLines :: [String] -> String
onSeparateLines [] = ""
onSeparateLines ( x:[] ) = x
onSeparateLines ( x:xs ) = x ++ "\n" ++ onSeparateLines xs
what I get is
"AAAA\nAAAA"
which should be:
"AAAA"
"AAAA"
The given function and your use of "\n" are correct, so the error must be elsewhere. Without knowing the details, I suspect that you are using (the equivalent of) print rather than putStr to print your string. Make sure that your string is not being shown before it is printed.
If this is in GHCi, be aware that values are printed using print, so
> onSeparateLines ["foo", "bar"]
will print the string and show escaped characters. You want
> putStrLn (onSeparateLines ["foo", "bar"])
instead.
Related
Right now I'm trying to make a basic function that removes any spaces or commas from a sentence.
stringToIntList :: [Char] -> [Char]
stringToIntList inpt = [ a | a <- inpt, a `elem` [" ",","]]
The problem I'm experiencing is that every type I've tried doesn't work, if I put [Char] it freaks out at commas, if I put [string] it freaks out at spaces, and if I put string it just doesn't recognize a and says it's an error. so I was wondering if there was some type that could work as both a [Char] and a [string].
With the current type, the definition needs to be
stringToIntList inpt = [ a | a <- inpt, a `elem` [' ',',']]
(single quotes, because these are Char literals, not String ones!),or alternatively
stringToIntList inpt = [ a | a <- inpt, a `elem` " ,"]
(using the fact that a string is just a list of characters),or simply
stringToIntList = filter (`elem` " ,")
Note that this doesn't remove spaces and commas, on the contrary those are the only characters it keeps. To remove them instead, you need to invert the predicate:
stringToIntList = filter $ not . (`elem` " ,")
As Iceland_jack comments, there is actually a standard function for this combination:
stringToIntList = filter (`notElem` " ,")
If you really did want a `elem` [" ",","] then the type of your function would need to be
stringToIntList :: [String] -> [String]
or equivalently [[Char]] -> [[Char]].
I've been looking through previously asked questions and I can't find an answer that solves my problem, although I thought at least one of them would. I'm simply trying to have a newline character added between my strings inside of a function. Whenever I add a "\n" to a string, it simply prints the "\n"
import Data.List
-- aRow takes number of columns as argument
-- The idea is to use this function with the number of columns as argument.
-- Example, if we want 3 columns, we'd say aRow 3, and get "+---+---+---+"
aRow :: Int -> String
aRow n = "+" ++ take (4*n) (intercalate "" (repeat "---+")) ++ "\n|" ++ take (4*n) (intercalate "" (repeat " |"))
This is the output I'm getting
"+---+---+---+---+\n| | | | |"
and I'd prefer
"+---+---+---+---+"
"| | | | |"
Where the lines are on separate lines (Also there's supposed to be 3 spaces between the vertical bars, ignore my formatting. I'm mainly trying to get the newline character working). Thank you.
https://stackoverflow.com/a/5944062/1848654:
If you just evaluate a string expression in ghci without using putStr or putStrLn, it will just call show on it, so for example the string "foo\n" will display as "foo\n" in ghci, but that does not change the fact that it's a string containing a newline and it will print that way, once you output it using putStr.
Long story short, you may want to use putStr as Haskell will default to using show on that string and that will display the \n plainly as it has done for you here.
Example:
import Data.List
main = putStrLn(aRow 4)
aRow :: Int -> String
aRow n = "+" ++ take (4*n) (intercalate "" (repeat "---+")) ++ "\n|" ++ take (4*n) (intercalate "" (repeat " |"))
I've written a basic recursive function:
bibliography_rec :: [(String, String, Int)] -> String
bibliography_rec [] = ""
bibliography_rec (x:xs) = (citeBook x) ++ "\n" ++ (bibliography_rec xs)
citeBook simply reformats the tuple into a String.
When run with this input:
ghci> bibliography_rec [("Herman Melville", "Moby Dick", 1851),("Georgy Poo", "Alex Janakos", 1666)]
It produces:
"Moby Dick (Herman Melville, 1851)\nAlex Janakos (Georgy Poo, 1666)\n"
I need line by line printing so I used this:
bibliography_rec (x:xs) = putStr ((citeBook x) ++ "\n" ++ (bibliography_rec xs))
My problem is my output NEEDS to be of type String NOT IO ()
I've been stuck on this for way too long so any help is great!
Looks like you're already there, you just need to putStrLn the string instead of printing it (which is what ghci does by default). print runs its argument through show first, so it will quote the escape characters like "\n".
ghci> putStrLn $ bibliography_rec [...]
Been messing around for about 20 minutes now trying to get the new line working however it always shows in GHCI as a single line.
Here is what I enter into GHCi:
displayFilm ("Skyfall",["Daniel Craig", "Judi Dench", "Ralph Fiennes"], 2012, ["Bill", "Olga", "Zoe", "Paula", "Megan", "Sam", "Wally"])
Here is what is printed:
"Skyfall----------\n Cast: Daniel Craig, Judi Dench, Ralph Fiennes\n Year: 2012\n Fans: 7\n"
displayList :: [String] -> String
displayList [] = ""
displayList [x] = x ++ "" ++ displayList []
displayList (x:xs) = x ++ ", " ++ displayList xs
displayFilm :: Film -> String
displayFilm (title, cast, year, fans) =
title ++ "----------" ++
"\n Cast: " ++ (displayList cast) ++
"\n Year: " ++ (show year) ++
"\n Fans: " ++ show (length fans) ++ "\n"
To print a string as it is, without escaping special characters, use:
putStr string
or
putStrLn string
if you want an extra newline at the end. In you case, you are probably looking for
putStr (displayFilm (....))
Why is this needed? In GHCi, if you evaluate an expression s the result will be printed as if running print s (unless it has type IO something -- forget about this special case). If e is a string, print escapes all the special characters and output the result. This is because print is meant to output a string whose syntax follows the one in Haskell expressions. For numbers, this is the usual decimal notation. For strings, we get quotes and escaped characters.
When you type an expression into GHC, it displays it using print. Calling print on a string shows its content but does not evaluate escape sequences:
> print "line1\nline"
"line1\nline2"
Note the quotes.
To display the string as you desire, use putStr or putStrLn (the latter will append a newline).
> putStr "line1\nline2"
line1
line2
My goal is to find the number of times a substring exists within a string.
The substring I'm looking for will be of type "[n]", where n can be any variable.
My attempt involved splitting the string up using the words function,
then create a new list of strings if the 'head' of a string was '[' and
the 'last' of the same string was ']'
The problem I ran into was that I entered a String which when split using
the function words, created a String that looked like this "[2],"
Now, I still want this to count as an occurrence of the type "[n]"
An example would be I would want this String,
asdf[1]jkl[2]asdf[1]jkl
to return 3.
Here's the code I have:
-- String that will be tested on references function
txt :: String
txt = "[1] and [2] both feature characters who will do whatever it takes to " ++
"get to their goal, and in the end the thing they want the most ends " ++
"up destroying them. In case of [2], this is a whale..."
-- Function that will take a list of Strings and return a list that contains
-- any String of the type [n], where n is an variable
ref :: [String] -> [String]
ref [] = []
ref xs = [x | x <- xs, head x == '[', last x == ']']
-- Function takes a text with references in the format [n] and returns
-- the total number of references.
-- Example : ghci> references txt -- -> 3
references :: String -> Integer
references txt = len (ref (words txt))
If anyone can enlighten me on how to search for a substring within a string
or how to parse a string given a substring, that would be greatly appreciated.
I would just use a regular expression, and write it like this:
import Text.Regex.Posix
txt :: String
txt = "[1] and [2] both feature characters who will do whatever it takes to " ++
"get to their goal, and in the end the thing they want the most ends " ++
"up destroying them. In case of [2], this is a whale..."
-- references counts the number of references in the input string
references :: String -> Int
references str = str =~ "\\[[0-9]*\\]"
main = putStrLn $ show $ references txt -- outputs 3
regex is huge overkill for such a simple problem.
references = length . consume
consume [] = []
consume ('[':xs) = let (v,rest) = consume' xs in v:consume rest
consume (_ :xs) = consume xs
consume' [] = ([], [])
consume' (']':xs) = ([], xs)
consume' (x :xs) = let (v,rest) = consume' xs in (x:v, rest)
consume waits for a [ , then calls consume', which gathers everything until a ].
Here's a solution with
sepCap.
import Replace.Megaparsec
import Text.Megaparsec
import Text.Megaparsec.Char
import Data.Either
import Data.Maybe
txt = "[1] and [2] both feature characters who will do whatever it takes to " ++
"get to their goal, and in the end the thing they want the most ends " ++
"up destroying them. In case of [2], this is a whale..."
pattern = single '[' *> anySingle <* single ']' :: Parsec Void String Char
length $ rights $ fromJust $ parseMaybe (sepCap pattern) txt
3