Getting a string from a IO ExitCode monad - haskell

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.

Related

Basic error with `putStrLn` in Haskell. VScode extension Haskelly [duplicate]

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.

A mystery involving putStrLn

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.

Add a typeclass constraint on a Record type

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 ?

make entire list to string in erlang

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]"

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