make entire list to string in erlang - string

I'm trying to do the following
S = lists:concat(A) ++ " " ++ [254,874] ++ "\n".
it gives me error message
** exception error: no match of right hand side value [51,50,52,51,53,54,53,54,55,54,54,53,52,51,32,254,874,10]
but it works fine for string values "[254,874]"
how can I make [254,874] to "[254,874]"

You maybe forgot f(S) for previous calculation. Try it before using your command:
1> f(S).
ok
2> S = lists:concat(A) ++ " " ++ [254,874] ++ "\n".
Moreover, you can use $[ or $] for indicate "[" "]" in ASCII
3> $[.
91
4> $].
93
5> S = lists:concat(A) ++ " " ++ [91,254,874,93] ++ "\n".

found the answer
A = [254,876].
lists:flatten(io_lib:format("~p",[A])).
this gives exact result
"[254,876]"

To convert list of integers to string
for your case I would have done:
[A, B] = [254,876],
C = "[" ++ integer_to_list(A) ++ "," ++ integer_to_list(B) ++ "]".
for a more generic case:
-module(l2s).
-compile(export_all).
list_to_string([H|List]) ->
list_to_string(List, "[" ++ integer_to_list(H)).
list_to_string([], String) -> String ++ "]";
list_to_string([H | List], String) ->
list_to_string(List, String ++ "," ++ integer_to_list(H)).
Test:
Eshell V7.3 (abort with ^G)
1> A = [1,2,3,4,5].
[1,2,3,4,5]
2> l2s:list_to_string(A).
"[1,2,3,4,5]"

"["++lists:concat(lists:join(",",A))++"]".
"[1,2,3,4]"

Related

Function expects Char in place of [Char]

I am new to Haskell and functional programming, and can't understand why this function cannot identify the correct type:
mformat :: [Char] -> [Char] -> [Char]
mformat first last = ((formatted first last) ++ " " ++ first ++ " " ++ last ++ ".")
where formatted (f:_) (l:_) = (f ++ "." ++ l ++ ".")
which causes the error:
teststuff.hs:42:40: error:
* Couldn't match type `Char' with `[Char]'
Expected: [[Char]]
Actual: [Char]
* In the second argument of `formatted', namely `last'
In the first argument of `(++)', namely `(formatted first last)'
In the expression:
(formatted first last) ++ " " ++ first ++ " " ++ last ++ "."
|
42 | mformat first last = ((formatted first last) ++ " " ++ first ++ " " ++ last ++ ".")
| ^^^^
Failed, no modules loaded.
I don't understand what is wrong here, any help would be appreciated.
The issue is in your formatted function. You are pattern matching on a String, you get Chars (f & l) and then you try concatenating them with a String. You cannot concatenate a Char with a String ([Char]).
mformat :: String -> String -> String
mformat first last = ((formatted first last) ++ " " ++ first ++ " " ++ last ++ ".")
where
formatted :: String -> String -> String
formatted (f:_) (l:_) = ([f] ++ "." ++ [l] ++ ".")
or
-- ...
formatted (f:_) (l:_) = (f : "." ++ l : ".")
The type checker thinks thinks that f and l in your case must be lists - because you are attempting to concatenate them. Then it infers (via pattern matching) from the list constructor, that first and last are lists of Strings i.e. [String] or [[Char]].

Haskell : list comprehension

How can I write this code without repeating (c !! x) where is x = [0..7], using list comprehension is better but I couldn't figure how to write it
show (EOBoard f c r) = "EOBoard\n" ++ "Foundations "
++ show f ++ "\n" ++ "Columns \n"
++ show (c!!0) ++ "\n" ++ show (c!!1) ++ "\n"
++ show (c!!2) ++ "\n" ++ show (c!!3) ++ "\n"
++ show (c!!4) ++ "\n" ++ show (c!!5) ++ "\n"
++ show (c!!6) ++ "\n" ++ show (c!!7) ++ "\n"
++ "Reserves " ++ show r
Let's start by getting rid of all those manual line breaks.
import Data.List
show (EOBoard f c r) = intercalate "\n" $
[ "EOBoard"
, "Foundations " ++ show f
, "Columns"
, show (c!!0)
, show (c!!1)
, show (c!!2)
, show (c!!3)
, show (c!!4)
, show (c!!5)
, show (c!!6)
, show (c!!7)
, "Reserves " ++ show r]
Note: if you want a line break at the end too, use unlines instead of intercalate.
As you noticed, there's a rather repetitive section. Also, those !! applications are kind of expensive. A list comprehension solves both problems, but I'd use map instead.
show (EOBoard f c r) = intercalate "\n" $
[ "EOBoard"
, "Foundations " ++ show f
, "Columns" ] ++
map show c ++
["Reserves " ++ show r]
(map show c could be replaced by [show x | x <- c] if you prefer.)
There's still something funny; Show really isn't for pretty-printing. show shouldn't insert line breaks. You probably actually want to write a custom pretty-printing function instead.
What you wrote is equivalent to
show (EOBoard f c r) = "EOBoard\n" ++ "Foundations "
++ show f ++ "\n" ++ "Columns \n" ++
++ concat [ show s ++ "\n" | s <- take 8 c]
++ "\n" ++ "Reserves " ++ show r
which is equivalent to
show (EOBoard f c r) = "EOBoard\n" ++ "Foundations "
++ show f ++ "\n" ++ "Columns \n" ++
++ [ ch | s <- take 8 c, ch <- show s ++ "\n" ]
++ "\n" ++ "Reserves " ++ show r
or, using the concat more instead of inlining it, it is equivalent to
show (EOBoard f c r) = concat (
[ "EOBoard\n", "Foundations ", show f, "\n", "Columns \n" ]
++ [ show s ++ "\n" | s <- take 8 c]
++ ["\n" , "Reserves " , show r] )
which is normally written with the $ operator, as
show (EOBoard f c r) = concat $
[ "EOBoard\n", "Foundations ", show f, "\n", "Columns \n" ]
++ [ show s ++ "\n" | s <- take 8 c]
++ ["\n" , "Reserves " , show r]

Haskell new line not working

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

Getting a string from a IO ExitCode monad

I'm trying to concatenate a string given as an argument (using getArgs) to the haskell program, e.g.:
"rm " ++ filename ++ " filename2.txt" which is inside a main = do block.
The problem is with the type of filename, and ghc won't compile it, giving an error.
I get an error Couldn't match expected type [a] against inferred type IO ExitCode
the code we're trying to run is:
args <- getArgs
let inputfname = head args
system "rm -f "++ inputfname ++ " functions.txt"
You need $:
system $ "rm -f "++ inputfname ++ " functions.txt"
Or parentheses:
system ("rm -f " ++ inputfname ++ " functions.txt")
Otherwise you’re trying to run this:
(system "rm -f ") ++ inputfname ++ " functions.txt"
It fails because ++ wants [a] (in this case String) but gets IO ExitCode (from system).
The problem is that function application has higher precedence than the (++) operator, so it parses as
(system "rm -f ") ++ inputfname ++ " functions.txt"
while what you meant was
system ("rm -f " ++ inputfname ++ " functions.txt")
or simply
system $ "rm -f " ++ inputfname ++ " functions.txt"
The following code works:
import System.Process
import System.Environment
main = do
args <- getArgs
let inputfname = head args
system $ "rm -f "++ inputfname ++ " functions.txt"
The reasons were explained by other commenters.

Newline in Haskell String?

How can I create a newline inside a String? Is it possible without using IO ()?
formatRow :: Car -> String
formatRow (a, d:ds, c, x:xs) = a ++ " | " ++ x ++ concat xs ++ " | " ++ show c ++ " | " ++ d ++ concat ds ++ (show '\n')
To create a string containing a newline, just write "\n".
If you run your program on Windows, it will automatically be converted to "\r\n".
Note that calling show on it will escape the newline (or any other meta-characters), so don't do foo ++ (show "\n") or foo ++ (show '\n') - just use foo ++ "\n".
Also note that 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.

Resources