This question already has answers here:
A mystery involving putStrLn
(2 answers)
Closed 3 years ago.
main = do line <- getLine
let line' = reverse line
putStrLn $ "You said " ++ line' ++ " backwards!"
putStrLn $ "Yes, you really said " ++ line ++ " backwards!"
Error:
$ stack runhaskell "c:\Users\FruitfulApproach\Desktop\Haskell\test.hs"
C:\Users\FruitfulApproach\Desktop\Haskell\test.hs:4:5: error:
parse error on input `putStrLn'
|
4 | putStrLn $ "You said " ++ line' ++ " backwards!"
| ^^^^^^^^
I've also tried it with a single tab on the indented lines.
Here's my tabs -> spaces setting:
I've also tried restarting VSCode.
Thanks in advance!
I believe your code is insufficiently indented. Try this:
main = do line <- getLine
let line' = reverse line
putStrLn $ "You said " ++ line' ++ " backwards!"
putStrLn $ "Yes, you really said " ++ line ++ " backwards!"
Specifically, your lines following the do should be indented just as much as the thing that comes after it, namely line <- getLine.
Why does the piece of code below produce the error parse error on input ‘putStrLn’?
main = do line <- fmap reverse getLine
putStrLn $ "You said " ++ line ++ " backwards!"
putStrLn $ "Yes, you said " ++ line ++ " backwards!"
<interactive>:11:4: error: parse error on input ‘putStrLn’
Also, why does the following piece of code produce the error parse error on input ‘let’?
main = do line <- getLine
let line' = reverse line
putStrLn $ "You said " ++ line' ++ " backwards!"
putStrLn $ "Yes, you said " ++ line' ++ " backwards!"
<interactive>:31:4: error: parse error on input ‘let’
Both snippets have the same problem. If you put the first action of a do block on the same line as the do itself, you still have to indent the rest of the actions in the do block as far as the first one. Two choices to fix it:
main = do line <- fmap reverse getLine
putStrLn $ "You said " ++ line ++ " backwards!"
putStrLn $ "Yes, you said " ++ line ++ " backwards!"
or
main = do
line <- fmap reverse getLine
putStrLn $ "You said " ++ line ++ " backwards!"
putStrLn $ "Yes, you said " ++ line ++ " backwards!"
It also works when explicit separators are used throughout:
main = do { line <- fmap reverse getLine ;
putStrLn $ "You said " ++ line ++ " backwards!" ;
putStrLn $ "Yes, you said " ++ line ++ " backwards!" }
main = do { line <- getLine ;
let { line' = reverse line } ; -- NB let's { }s
putStrLn $ "You said " ++ line' ++ " backwards!" ;
putStrLn $ "Yes, you said " ++ line' ++ " backwards!" }
This is not a substitute for the good indentation style, but an addition to it.
Before this declaration was working well in my context :
data PersistedCommand = PersistedCommand { offset :: Offset , command :: Command }
instance Show PersistedCommand where
show persistedCommand = "PersistedCommand { offset = " ++ ( show $ offset persistedCommand) ++ " , command = " ++ (show $ getCommandName $ command persistedCommand) ++ ":"
++ (show $ getAggregateId $ command persistedCommand) ++ " }"
But I've changed Command from a data type to a type class. How do I express this now in the previous declaration ?
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]"
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.