Cannot get main function to compile in Haskell - haskell

I am relatively new to Haskell and everything I have done has been completed through GHCi, however, now I am trying to compile using GHC, however, I constantly get the error message The IO action ‘main’ is not defined in module ‘Main’, I have tried declaring main = do, however, I receive more errors then, namely parse error on input ‘=’ from the line fib 0 = 1.
Here is the code I am working with:
module Main where
fib :: Integer -> Integer
fib 0 = 1
fib 1 = 1
fib x = fib (x - 1) + fib (x - 2)
Thanks for any help in advance!

You should write something like:
module Main where
fib :: Integer -> Integer
fib 0 = 1
fib 1 = 1
fib x = fib (x - 1) + fib (x - 2)
main :: IO ()
main = do
print $ fib 10
Note: your fib function should not be indented, it should be left aligned.

Because main should be of type IO (). Something like this should work:
main = print $ fib 3
Your entire program should look like this:
module Main where
fib :: Integer -> Integer
fib 0 = 1
fib 1 = 1
fib x = fib (x - 1) + fib (x - 2)
main = print $ fib 3
Notice the space difference between your code and the above one in the fib function.
I have tried declaring main = do
main = do just doesn't make any sense for the compiler. Remember do is a syntax sugar for monads. do is not a valid expression.

Related

Haskell Says My Guard Has A Parse Error

So I've been playing with Haskell the past couple of days, and I decided I'd make a basic definition of the Fibonacci sequence. So I wrote this code:
main = do
fib :: (Integral a) => Int -> Int
fib x
| x == 0 = 0
| x == 1 = 1
| x >= 2 = fib (x - 2) + fib (x - 1)
do { print (fib 5) }
And I get an error message saying:
4:17: parse error on input `|'
I suspected tab errors, so I tried every whitespace fix I could find, but I just can't find what's wrong!
EDIT: So I did what people suggested, and I have this code now:
fib :: (Integral a) => Int -> Int
main = do
fib x
| x == 0 = 0
| x == 1 = 1
| x >= 2 = fib (x - 2) + fib (x - 1)
print (fib 5)
And I'm getting the same error.
You should define fib outside of main, not inside it. And then you should remove at least one of the dos from main.
The problem is that you are trying to define the function within do block without actually using any construct for defining things (like let).
Try defining the function outside the block:
fib :: (Integral a) => Int -> Int
fib x | x == 0 = 0
| x == 1 = 1
| x >= 2 = fib (x - 2) + fib (x - 1)
main = print (fib 5)
If you insist on defining the function locally (inside the expression that is formed by statements of the do block):
main = do
let
fib :: (Integral a) => Int -> Int
fib x | x == 0 = 0
| x == 1 = 1
| x >= 2 = fib (x - 2) + fib (x - 1)
print (fib 5)
Notice how let is used to bind a new variable fib to the function you want.
You can also define fib locally to main outside of the do block. Do bear in mind that do is syntactic sugar for the use of various monadic binding functions, and so the syntax accepted within it is not quite the same as that accepted outside it. And, in fact, your main doesn't even require the do block because you just call print rather than chaining any IO actions together.
main = let
fib x | x == 0 = 0
| x == 1 = 1
| x >= 2 = fib (x - 2) + fib (x + 1)
in
print (fib 5)
Or you could use where:
main = print (fib 5)
where
fib x | x == 0 = 0
| x == 1 = 1
| x >= 2 = fib (x - 2) + fib (x + 1)
They're the same, the question is just where the local binding actually goes. let..in gives you a new block where the new bindings are in scope, while where makes its bindings available in the scope of the function it's attached to.
If, as seems eventually likely, you do want a do block as well so you can do multiple IO actions, you can just put that in place of the call to print, like so:
main = let
fib x | x == 0 = 0
| x == 1 = 1
| x >= 2 = fib (x - 2) + fib (x + 1)
in
do print (fib 5)
print (fib 6)

Why do I get a parser error in my program?

I've written a Haskell program for problem 25 on Euler. I think my program should run and return the correct answer, but it doesn't:
-- Problem25.hs
module Main where
fib :: Int -> Integer
fib 1 = 1
fib 2 = 1
fib n = fib (n-1) + fib (n-2)
length1 :: Integer -> Int
length1 = length . show
main :: IO ()
main = do
list1 <- [1..]
list2 <- zip3 list1 list1 list1
list3 <- map funct list2
where funct u v w = (u, fib u, length1 (fib u))
putStrLn "number : " -- line 17
putStrLn $ show . head . ( dropWhile ( \(u,v,w)-> w < 1000 ) list3)
However, I get the following error:
$ ghc Problem25.hs
[1 of 1] Compiling Main ( Problem25.hs, Problem25.o )
Problem25.hs:17:3: parse error on input `putStrLn'
Why do I get the parser error? I'm in a do block, so putStrLn "number : " should be fine, right?
ok here is a version with all syntax errors removed:
module Main where
fib :: Int -> Integer
fib 1 = 1
fib 2 = 1
fib n = fib (n-1) + fib (n-2)
length1 :: Integer -> Int
length1 = length . show
main :: IO()
main = do
putStrLn "hello"
let liste = [1..]
let liste2 = zip3 liste liste liste
let liste3 = map funct liste2
putStrLn "number : "
putStrLn $ show . head $ (dropWhile ( \(_,_,w)-> w < 1000 ) liste3)
where funct (u,_,_) = (u,fib u,length1 (fib u))
as you can see there are quite a few:
where in the middle of a do block -> this has to go to the end
<- instead of let ... = ... - remember: <- is to pull out values form computations - in this case to get an a from an IO a
one . to many in the last putStrLn (the last part with dropWhile is a value not a function)
a few places where you have to use a 3-tuple argument instead of the curried version as you choose to go with zip3 (that returns tuples)
also note that while this compiles and runs it will most likely not be a good (or even feasible) solution - I did nothing more than remove your syntax problems - to get a good solution you should first work on your fib (which does not perform very well - there are better ways to compute it - hint: search for Haskell + Fib on your fav. search engine)
here are a few remarks:
you don't need the zip3 part with 3 times the same list - you can let your funct do this work (which btw: you already do - you ignore the second and third argument)
why do you dropWhile and then take the head? (filter and head seems more natural IMO)
of course you should also rethink the funct part (notice how you never need the middle item from the tuples?)
Good luck with the rest of the exercise ;)
a bit cleaned up
I cleaned up your solution a bit:
fib :: Int -> Integer
fib 1 = 1
fib 2 = 1
fib n = fib (n-1) + fib (n-2)
length1 :: Integer -> Int
length1 = length . show
solve :: Int
solve = head . filter ((>= 1000) . length1 . fib) $ [1..]
main :: IO()
main = do
putStrLn "number : "
print solve
that's still not better performance wise (that's your challange) but at least it works for 3 digits instead of 1000 (although even 10 will take quite some time with this ...)
enjoy
cannot help it
I had to try it and indeed if you define the sequence like this:
import Data.List (unfoldr)
fibs :: [Integer]
fibs = unfoldr fib (1,1)
where fib (n,m) = Just (n,(m,n+m))
(which is near to what you would usually do in a loop)
you get the answer rather quickly (4782)
of course you have to think about how to get the index to this (hint: now a zip might be a good idea)

What's wrong with my Fibonacci implementation?

I'm trying to transform my recursive Fibonacci function into an iterative solution. I tried the following:
fib_itt :: Int -> Int
fib_itt x = fib_itt' x 0
where
fib_itt' 0 y = 0
fib_itt' 1 y = y + 1
fib_itt' x y = fib_itt' (x-1) (y + ((x - 1) + (x - 2)))
I want to save the result into variable y and return it when the x y matches with 1 y, but it doesn't work as expected. For fib_itt 0 and fib_itt 1, it works correctly, but for n > 1, it doesn't work. For example, fib_rek 2 returns 1 and fib_rek 3 returns 2.
Your algorithm is wrong: in y + (x-1) + (x-2) you only add up consecutive numbers - not the numbers in the fib.series.
It seems like you tried some kind of pair-approach (I think) - and yes it's a good idea and can be done like this:
fib :: Int -> Int
fib k = snd $ fibIt k (0, 1)
fibIt :: Int -> (Int, Int) -> (Int, Int)
fibIt 0 x = x
fibIt k (n,n') = fibIt (k-1) (n',n+n')
as you can see: this passes the two needed parts (the last and second-to-last number) around as a pair of numbers and keeps track of the iteration with k.
Then it just gives back the second part of this tuple in fib (if you use the first you will get 0,1,1,2,3,... but of course you can adjust the initial tuple as well if you like (fib k = fst $ fibIt k (1, 1)).
by the way this idea directly leeds to this nice definition of the fib.sequence if you factor the iteration out to iterate ;)
fibs :: [Int]
fibs = map fst $ iterate next (1,1)
where
next (n,n') = (n',n+n')
fib :: Int -> Int
fib k = fibs !! k

Partial memoization in Haskell

I'm trying to find a good way to memoize a function for only part of its domain (non-negative integers) in Haskell, using Data.MemoCombinators.
import Data.MemoCombinators
--approach 1
partFib n | n < 0 = undefined
| otherwise = integral fib n where
fib 0 = 1
fib 1 = 1
fib k = partFib (k-1) + partFib (k-2)
--approach 2
partFib2 n | n < 0 = undefined
| otherwise = fib n
fib = integral fib'
where
fib' 0 = 1
fib' 1 = 1
fib' n = partFib2 (n-1) + partFib2 (n-2)
Approach 1 is how I would like to do it, however, it doesn't seem to work. I assume this is because the fib function is "recreated" every time partFib is called, throwing away the memoization. fib doesn't depend on the input of partFib, so you would assume that the compiler could hoist it, but apparently GHC doesn't work that way.
Approach 2 is how I end up doing it. Eerk, a lot of ugly wiring.
Does anybody know of a better way to do this?
Not quite sure what's "ugly" to your eye, but you can have proper memoization while using only a single top-level identifier by lifting the memoization operation out of the function of n.
partFib3 = \n -> if n < 0 then undefined else fib' n
where fib 0 = 1
fib 1 = 1
fib k = partFib3 (k-1) + partFib3 (k-2)
fib' = integral fib
Hmm what about separating things a bit:
fib 0 = 0
fib 1 = 1
fib x = doFib (x-1) + doFib (x-2)
memFib = Memo.integral fib
doFib n | n < 0 = fib n
| otherwise memFib n
Now you need to use doFib.
There is a combinator in the library for this purpose:
switch :: (a -> Bool) -> Memo a -> Memo a -> Memo a
switch p a b uses the memo table a whenever p gives true and the memo table b whenever p gives false.
Recall that id is technically a memoizer (which does not memoize :-), so you can do:
partFib = Memo.switch (< 0) id Memo.integral fib'
where
...

Haskell Error - Naked Expression at Top Level

I have the following code:
fib n
| n == 0 = 0
| n == 1 = 1
| n > 1 = fib (n-1) + fib (n-2)
print fib 5
And for some reason, it's throwing an error:
[1 of 1] Compiling Main ( test.hs, test.o )
test.hs:8:1: Parse error: naked expression at top level
What's going on?
You cannot have an expression at the top-level. Haskell program entry point is a main function in Main module. Also print fib 5 calls print with two arguments, you need to do:
main = print $ fib 5
or
main = print (fib 5)

Resources