Confused on how to understand `main` in I/O action?

I’m studying Chapter Input and Output in the book Learn You a Haskell For Great Good. I try to have a basic understanding of why I/O actions will only be performed when they are given a name of main.

To my experience, in Haskell we use = to declare function name and define the function body.

So in my point of view,

main = putStrLn "I like you."

is just a “const” function takes no input and returns a term of type “IO ()”, where IO here is a type constructor IO :: * -> * and according to the text, () is the unit type also a concrete type. So I think the name main is changable. And I declare main' as follows :

-- main = putStrLn "I like you."

main' :: IO ()
main' = putStrLn "I like you."

Unfortunatly, Haskell warns me that the I/O action is not defined. This looks confused to me, since in GHCI I’m allowed to do the following things :

λ> main = putStrLn "I like you."
λ> main
I like you.

λ> main' = putStrLn "I like you."
λ> main'
I like you.

I don’t know why main and main' behave so different outside of the GHCI prompt!

1 Like

It makes a difference to the runtime, which loads a function called main.

It has a very similar purpose to main function in C, or __main__ in python: Being the entry point of the program.

The error message is very confusing. When you call GHC on a file without a module name, then it defaults to Main which must have a main function.

You can write your custom main' function in a file and have it compile properly, but then you have to give your module another name. For example you can write this:

module Foo where
main' = putStrLn "I like you"

This compiles without errors (but it does not produce an executable because there is no entrypoint).

Oh! I see the problem! It seems like Emacs’s Haskell-mode automatically import some modules for me which cause the warning.
BTW thanks for explaining the process! I think I understand better now!

You have your answer, but next time you run into a confusing error message please check out this site:

https://errors.haskell.org/

Also, maybe you can contribute by adding new explanations.

1 Like

Sadly, it’s not documented yet: https://errors.haskell.org/messages/GHC-67120. Edit: I’ve made a PR: Add GHC-67120 `main` not defined by noughtmare · Pull Request #555 · haskellfoundation/error-message-index · GitHub

Also, the error code is only shown on GHC 9.8 or later, while GHCup still recommends 9.4.

3 Likes

My PR has now been merged! You can see the explanation on the error message index:

https://errors.haskell.org/messages/GHC-67120/

4 Likes