I'm having a problem figuring out why I am getting a parse error when compiling code. I've tried indenting using tabs and spaces yet no success. Maybe I just need another set of eyes on the code, any help would be greatly appreciated!
The error seems to be coming from this line:
putStrLn "\nSelected option: "
main :: IO()
main = do contents <- readFile "films.txt";
let database = (read contents :: [Film])
putStrLn "Please enter your name:";
name <- getLine;
putStrLn ("Hello " ++ name ++ "!");
menu database
where menu newDb = do putStrLn "\nWhat would you like to do?";
putStrLn "1 -> Add a film";
putStrLn "2 -> Display all films";
putStrLn "3 -> Display all films by director's name";
putStrLn "4 -> Display the films of an average website rating";
putStrLn "5 -> Display the average rating of the films of a particular actor";
putStrLn "6 -> Show the films you have rated, with the rating";
putStrLn "7 -> Rate or ReRate a film";
putStrLn "8 -> Display films released during or after a year, sorted in descending order of rating";
putStrLn "9 -> Exit & Save";
putStrLn "\nSelected option: "
option <- getLine
case option of
"1" -> do putStr "Name of Film: "
title <- getLine
putStr "Name of the Director: "
director <- getLine
putStr "Year the film was released: "
year <- getLine
putStrLn (map formatFilmOutput $ addFilm title director (read year) [] newDb)
"2" -> do putStrLn (displayAllFilm newDb) >> menu newDb
"I've tried indenting using tabs and spaces yet no success." - there's your problem. Find an editor that will, upon saving a file, replace tabs with spaces; or set your tab stops to be 8 characters.
The Haskell Report, section 10.3:
Tab stops are 8 characters apart.
http://www.haskell.org/onlinereport/haskell2010/haskellch10.html#x17-17800010.3
Related
This question already has answers here:
Why "Empty do" error when my do isn't empty?
(3 answers)
Closed 2 years ago.
I have editing this code for hours just trying to get rid of this indentation problem and I followed the link I did previously. But because I follow those code I need to readjust again because my spaDatabase and updatedDB is not being recognised which I end up need to readjust everything from the top again and now the bottom part part has problem AGAIN.
I keep deleting and adding space but the error is still there. I also try based on one of the recommended answer I get this parse error below. But if I remove it, it end up being second parse error.
let output :: IO ()
parse error (possibly incorrect indentation or mismatched brackets)
--second error
parse error on input `='
Why "Empty do" error when my do isn't empty?
parse error on input `='
--line of error
output option = case option of
main :: IO()
main = do
contents <- readFile "spa.txt"
let spaDatabase = (read contents :: [Spa])
putStrLn "Please Enter Your Name: "
name <- getLine
putStrLn ("Welcome " ++ name)
putStrLn ""
let menu spaDatabase = do
putStrLn "\nPlease select an option:"
putStrLn "1: Add a new spa to the database "
option <- getLine
output :: IO ()
output option = case option of
1 -> do putStrLn "Enter Spa ID: "
rid <- getLine
let updatedDB = (addSpa rid br ar (read st) spaDatabase)
putStrLn (spaListStr updatedDB)
2 -> putStrLn (spaListStr updatedDB) >> menu spaDB
3 -> do putStrLn "Enter Spa Area:"
ar <- getLine
putStrLn (spaListStr (read ar) spaDatabase)
Here it is with the indents fixed. It's still not right: it defines menu and output but doesn't call them. But it should at least get you past the syntax errors.
main :: IO()
main = do
contents <- readFile "spa.txt"
let spaDatabase = (read contents :: [Spa])
putStrLn "Please Enter Your Name: "
name <- getLine
putStrLn ("Welcome " ++ name)
putStrLn ""
menu spaDatabase = do
putStrLn "\nPlease select an option:"
putStrLn "1: Add a new spa to the database "
getLine -- This returns the value, so no need for <-
output :: Int -> IO ()
output option = case option of
1 -> do
putStrLn "Enter Spa ID: "
rid <- getLine
let updatedDB = (addSpa rid br ar (read st) spaDatabase)
putStrLn (spaListStr updatedDB)
2 -> putStrLn (spaListStr updatedDB) >> menu spaDB
3 -> do
putStrLn "Enter Spa Area:"
ar <- getLine
putStrLn (spaListStr (read ar) spaDatabase)
I'm new to Haskell and would be glad if someone would be willing to help me! I'm trying to get this program to work with a do while loop.
The result from the second getLine command gets put into the varible goGlenn and if goGlenn doesn't equal "start" then the program will return to the beginning
start = do
loop $ do lift performAction
putStrLn "Hello, what is your name?"
name <- getLine
putStrLn ("Welcome to our personality test " ++ name ++ ", inspired by the Big Five Theory.")
putStrLn "You will receive fifty questions in total to which you can reply with Yes or No."
putStrLn "Whenever you feel ready to begin please write Start"
goGlenn <- getLine
putStrLn goGlenn
while (goGlenn /= "start")
In Haskell you write "loops" recursively, most of the times.
import Control.Monad
-- ....
start = do
putStrLn "Before the loop!"
-- we define "loop" as a recursive IO action
let loop = do
putStrLn "Hello, what is your name?"
name <- getLine
putStrLn $ "Welcome to our personality test " ++ name
++ ", inspired by the Big Five Theory."
putStrLn "You will receive fifty questions in total to which you can reply with Yes or No."
putStrLn "Whenever you feel ready to begin please write Start"
goGlenn <- getLine
putStrLn goGlenn
-- if we did not finish, start another loop
when (goGlenn /= "start") loop
loop -- start the first iteration
putStrLn "After the loop!"
Not sure, maybe this version can helps you:
import Control.Monad
loop action = do
condition <- action
when condition (loop action)
while = return
start =
let action = do {
putStrLn "Hello, what is your name?";
name <- getLine;
putStrLn ("Welcome to our personality test " ++ name ++ ", inspired by the Big Five Theory.");
putStrLn "You will receive fifty questions in total to which you can reply with Yes or No.";
putStrLn "Whenever you feel ready to begin please write Start";
goGlenn <- getLine;
putStrLn goGlenn;
while (goGlenn /= "start");
}
in loop action
(Edit) or can be too:
start =
loop (do {
putStrLn "Hello, what is your name?";
name <- getLine;
putStrLn ("Welcome to our personality test " ++ name ++ ", inspired by the Big Five Theory.");
putStrLn "You will receive fifty questions in total to which you can reply with Yes or No.";
putStrLn "Whenever you feel ready to begin please write Start";
goGlenn <- getLine;
putStrLn goGlenn;
while (goGlenn /= "start");
})
Shuklan's Haskell Lecture wanted the following code desugared:
main = do
putStrLn "Enter name:"
name <- getLine
putStrLn ("Hi " ++ name)
I came up with:
main = putStrLn "Enter name:" >> getLine >>= \str -> putStrLn ("Hi " ++ str)
He revealed:
main = putStrLn "Enter name:" >> getLine >>= putStrLn . ("Hi " ++)
Never seen that syntax before, how does it work?
The snippets are identical, the latter just uses point free style (also punningly referred to as "pointless style").
The central point is that ("Hi " ++) is a partially applied (++) that prepends "Hi " to the input.
This function is composed (using .) with putStrLn to get a function that prepends "Hi " to the input and then prints it.
This is exactly what your more explicit lambda does.
Based on other similar questions I found I figure my problem has to do with indentation, but I've messed with it a lot and still can't figure it out.
addBook = do
putStrLn "Enter the title of the Book"
tit <- getLine
putStrLn "Enter the author of "++tit
aut <- getLine
putStrLn "Enter the year "++tit++" was published"
yr <- getLine
In your case it's not indentation; you really have finished your function with something that is not an expression. yr <- getLine — what did you expect to happen to yr, or for that matter aut, after this? They're just dangling, unused.
It may be clearer to show how this translates:
addBook = putStrLn "Enter the title of the Book" >>
getLine >>= \tit ->
putStrLn "Enter the author of "++ tit >>
getLine >>= \aut ->
putStrLn "Enter the year "++tit++" was published" >>
getLine >>= \yr ->
So, what did you want to have following that last arrow?
Think about the type of addBook. It's IO a where a is... nothing. That doesn't work. Your monad must have some result.
You might want to add something like this at the end:
return (tit, aut, yr)
Alternatively, if you don't want to have any useful result, return an empty tuple (a unit):
return ()
If you take your code:
addBook = do
putStrLn "Enter the title of the Book"
tit <- getLine
putStrLn "Enter the author of "++tit
aut <- getLine
putStrLn "Enter the year "++tit++" was published"
yr <- getLine
and "translate" it to "normal" (non-do) notation (given p = putStrLn "..."):
addBook =
p >> getLine >>= (\tit ->
p >> getLine >>= (\aut ->
p >> getLine >>= (yr ->
You are ending up with (yr -> that doesn't make sense. If you don't have anything else useful to do, you can just return an empty tuple:
return ()
at the end:
addBook = do
putStrLn "Enter the title of the Book"
tit <- getLine
putStrLn "Enter the author of "++tit
aut <- getLine
putStrLn "Enter the year "++tit++" was published"
yr <- getLine
return ()
You should probably ask yourself why you need to get aut and yr though.
remove the last line since it's not an expression,
then use parenthesis for the strings you pass to putStrLn.
I am trying to make a program that reads a number given by a user and then prints it. the number has to be an integer when I print it, but this code gives me a parse error:
main = do
{
putStrLn "Please enter the number"
number <- getLine
putStrLn "The num is:" ++ show (read number:: Int)
}
If you use brackets in your do statement, you have to use semicolons. Also, the last line should be putStrLn $ "The num is:" ++ show (read number :: Int)
So you have two options:
main = do
{
putStrLn "Please enter the number";
number <- getLine;
putStrLn $ "The num is:" ++ show (read number:: Int)
}
or:
main = do
putStrLn "Please enter the number"
number <- getLine
putStrLn $ "The num is:" ++ show (read number:: Int)
Almost all of the code I've seen uses the second version, but they are both valid. Note that in the second version, whitespace becomes significant.
Haskell recognizes the Tab character and your program could be failing because of that. If you're using Tabs, change them to whitespaces.