Every function in Haskell returns a value of a certain type.
In this case, the doubleMe function returns a value of the Int type. When you load a file from the ghci interpreter, it loads all the functions from the file and makes them available to you.
The main function is a slightly special function, much like in other languages. It defines the entry point of a Haskell program. However, since it is just another Haskell function it too must return a value of a particular type. The main function is constrained to return a value of the IO type, most commonly IO ().
IO itself is quite special too, belonging to a class of types called monads. You can read up on the IO monad here.
Let us now return to your code:
main = do
doubleMe 2
Ignore the do syntax for a moment. You're basically telling the compiler that the main function returns doubleMe 2 which is of type Int. This won't fly. main has to return a value of IO type. In which case, you can use the return function to convert an Int value into an IO Int value. (return functions are functions that all monadic types must have. Very simply put, it converts a value of any type, into a monadic value.)
So this becomes:
main = do
return (doubleMe 2)
This is perfectly valid code, and will compile. However, once you run the program, you'll notice that it doesn't do anything. That's because the program returns the value 4.
In fact, you can write it without the do, and it becomes:
main = return (doubleMe 2)
This will work too.
Let us assume however, that you want to print out the value. This is where IO really comes in. Printing to a screen is an IO action.
main = do
print (doubleMe 2)
return (doubleMe 2)
A do expression allows you to chain a set of IO actions. So your program will still return the value 4 but it will first evaluate the expression print (doubleMe 2). As expected, that actually results in printing the value doubleMe 2.
Examine the print function in ghci.
> :t print
print :: Show a => a -> IO ()
The print function works on a value of any type that can be shown and it results in an IO action (printing to the screen) but returns nothing ().
All of these examples work, and will hopefully make things a little clear. (Look at the type signatures for main).
-- main :: IO Int
main = return (doubleMe 2)
-- main :: IO Int
main = do
print (doubleMe 2)
return (doubleMe 2)
-- main :: IO ()
main = do
print (doubleMe 2)
return ()
-- main :: IO ()
main = do
print (doubleMe 2)
-- main :: IO ()
main = print (doubleMe 2)
-- main :: IO ()
main = do
print "Hello"
print (doubleMe 2)
return ()
-- main :: IO String
main = do
print "Hello"
print (doubleMe 2)
return "Hello"
:l first.hsto load your definitions and thendoubleMe 2without the crufty edit-main-every-time-I-want-to-check-something faf. (See answers for advice on how to writemain.) - AndrewC