tags:

views:

276

answers:

2

Ok, so following on from my previous question I have ended up with the following code:

module Main where

import Data.List

chain n | n == 0     = error "What are you on about?"
     | n == 1    = [1]
     | rem n 2 == 0 = n : chain (n `div` 2) 
     | otherwise    = n : chain (3 * n + 1)


chainLength n =  (n,length (chain n))
array = map chainLength [1..999]
lengths = map chainLength [1..1000000]

compareSnd (_, y1) (_, y2) = compare y1 y2
longestChain = maximumBy compareSnd lengths

From the GHCi this loads fine as a module, but running longestChain ends up with a stack overflow. The resolution to this problem that isn't a complete rewrite is to increase the stack size. So I compile with: ghc --make chain.hs

I get an error:

chain.hs:1:0: The function 'main' is not defined in the module 'main'

Where do I need to put the main function in to make it compile properly.
Then once compiled, how do I make it run the output or use the command? I assume with:

ghc chain.o +RTS -K128M

Once compiled, I only need it to run longestChain with a large stack size.

+6  A: 

To compile an executable in Haskell you need to define a function called main. Something like this:

main = print longestChain

anywhere in the Main module.

Check out the GHC documentation on ghc --make.

Martinho Fernandes
Thanks, you're a lifesaver. My skill in Haskell has improoved greatly thanks to you're help.
Jonno_FTW
<nitpick>BTW, I noticed you are still calling array to those [] things. There are arrays in GHC, but they are not the same as *lists*. It helps to use correct terminology.</nitpick> If you want to learn the differences: http://www.cs.auckland.ac.nz/references/haskell/haskell-intro-html/arrays.html and http://www.haskell.org/tutorial/goodies.html
Martinho Fernandes
Call me when you get to the "evil" monads ;-)
Martinho Fernandes
+2  A: 

The problem in your program is that maximumBy apparently has a bug in it. You should report this to the GHC people :)

Here's a fixed version:

maximumByFixed :: (Ord a) => (a -> a -> Ordering) -> [a] -> a
maximumByFixed op (h:t) = step h t
    where
        step v [] = v
        step v (h:t)
            | v `op` h == LT
            = step h t
            | otherwise
            = step v t

As for why it won't build, you need to have a 'main' function, as Martinho says. That said, ghci's just a GHC program, you can always run:

ghci Main.hs +RTS -K128M

Of course, since your program takes quite a while to run, it's not a bad idea to compile it anyway. You can also compile a module for use with GHCI by adding exports and changing the name from Main:

module Chain (longestChain) where

Then run:

ghc -O2 --make Chain.hs

And then run ghci as normal:

ghci Chain.hs

This will load the compiled object automatically if it's up to date.

bdonlan
Fixed a small (but important!) error there, oops.
bdonlan
@bdonlan: there is no need for "Ord a" in maximumBy's context since it should only compare "a"s using the supplied comparison function.
yairchu