Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running a compiled Haskell program; getting errors

Tags:

haskell

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.

like image 298
Jonno_FTW Avatar asked Dec 29 '22 17:12

Jonno_FTW


2 Answers

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.

like image 134
R. Martinho Fernandes Avatar answered Jan 01 '23 06:01

R. Martinho Fernandes


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.

like image 27
bdonlan Avatar answered Jan 01 '23 05:01

bdonlan