With this code:
main :: FilePath -> FilePath -> IO ()
main wrPath rdPath = do x <- readFile rdPath
writeFile wrPath x
I got the following error:
Couldn't match expected type 'IO t0'
with actual type 'FilePath -> FilePath -> IO()
But the file compiles correctly when I change the name of 'main' to something else.
What's so unique about main and why does its type have to be IO t0
?
As in C, Java, or C#,
main
is a special identifier in certain contexts that indicates where the program should start.In Haskell,
main
is defined to have the typeIO a
. You should either give your function a different name, or if you really want it to be the starting point, change its signature and have it read the arguments from the command line withgetArgs
Although you didn't ask it specifically,
main
is also special in that it is the only function in a Haskell program that can (safely) invoke IO actions. The Haskell runtime treatsmain
as special.As GolezTrol said, all programs need to know which symbol to start executing when the function is invoked. Many scripting languages don't require (or just don't need) a
main
routine as they can have statements placed on the top level. This is not the case for Haskell, C and many others - these languages need a starting location and by convention that is themain
function (as per the Haskell spec - see Cat's answer).Notice Haskell's
main
does not accept any parameters that correspond to the program arguments - these are obtained viaSystem.Environment.getArgs
.Because the language spec says so.
By definition,
main
is a function that takes no arguments and returns a value of typeIO a
that is discarded by the runtime. What your error message is saying is that yourmain
does not comply with these requirements. This is indeed true, as yourmain
receives two parameters.In order to access command line parameters, use
System.Environment.getArgs
.