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.hs
to load your definitions and thendoubleMe 2
without the crufty edit-main-every-time-I-want-to-check-something faf. (See answers for advice on how to writemain
.) – AndrewC