0

I am getting acquainted to Haskell, currently writing my third "homework" to some course I found on the web. The homework assignment needs to be presented* in a file, named Golf.hs, starting with module Golf where. All well and good, this seems to be idiomatic in the language.

However, I am used to python modules ending in if __name__ == "__main__:, where one can put tests over the module, including during module development.ghc doesn't seem happy with such an approach:

$ ghc Golf.hs -o Golf && ./Golf

<no location info>: error:
    output was redirected with -o, but no output will be generated

Even though using cabal seems to be the norm, I would like to also understand the raw command-line invocations, that make programs work. ghci seems to be another approach to testing newly written code, yet reloading modules is peta. What is the easiest way to write some invocations of my functions with predefined test data and observe on stdout the result?

* - for students, who actually attend the course, I just follow the lecture notes and strive to complete the homeworks

Golf2.hs:

{-# OPTIONS_GHC -Wall #-}

module Golf2 where

foo :: Int -> Int
foo n = 42

main = putStr "Hello"

The output:

$ ghc Golf2.hs -o Golf2
[1 of 1] Compiling Golf             ( Golf2.hs, Golf2.o )

Golf2.hs:6:5: warning: [-Wunused-matches] Defined but not used: ‘n’

Golf2.hs:8:1: warning: [-Wmissing-signatures]
    Top-level binding with no type signature: main :: IO ()

<no location info>: error:
    output was redirected with -o, but no output will be generated
because there is no Main module.
7
  • 2
    I cannot reproduce that error. What's the minimal Golf.hs that reproduces that behaviour? Commented Apr 18, 2017 at 10:51
  • @Zeta I'm sure it's a silly question, and could probably resolve it by myself by rtfm, but there seem to pop too many of those questions at the moment. Commented Apr 18, 2017 at 10:57
  • 2
    As the error says, you should rename your module to Main or import it from another main module. Commented Apr 18, 2017 at 11:30
  • You can always reload a module using :reload in ghci. Commented Apr 18, 2017 at 11:32
  • @dimid the module and file are named as per the homework assignment. I was hoping to preserve the simple workflow "write functions -> write invocations with test data -> compile -> run -> observe stdout". reload-ing modules in ghci is extra steps. Writing a separate Main.hs, which imports Golf.hs is extra steps plus spatial fragmentation. Maybe runghc could aid me. I have never used it. Commented Apr 18, 2017 at 11:36

2 Answers 2

3

ghci is a really useful tool for learning!

When you only have one module, it's very easy, too. Start ghci, then :l Golf.hs. This will load your file. Then you'll be able to type foo 342 and see "42" displayed, or main and see "hello". You can edit the file, then use :reload or :r to load your changes. Real World Haskell has a good intro to using ghci.

This is a little easier than using ghc or tools like cabal, and all you really need while you're learning the very basics.

Sign up to request clarification or add additional context in comments.

1 Comment

This seems to be a classical example of XY problem. I was asking how to structure modules for testability, and the best solutions turns out to be ghci.
3

If you want to use ghc-the-compiler (instead of its interactive variant ghci), you might use the -main-is option.

From the docs:

-main-is⟨thing⟩

The normal rule in Haskell is that your program must supply a main function in module Main. When testing, it is often convenient to change which function is the “main” one, and the -main-is flag allows you to do so. The ⟨thing⟩ can be one of:

  • A lower-case identifier foo. GHC assumes that the main function is Main.foo.
  • A module name A. GHC assumes that the main function is A.main.
  • A qualified name A.foo. GHC assumes that the main function is A.foo.

So, try ghc -main-is Golf2 Golf2.hs -o Golf2 && ./Golf2.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.