What is wrong with this code? Trying to do a basic haskell hello world.
module Main
( hello )
where
hello :: [Char] -> [Char]
hello p = "Hello " ++ p ++ "!"
main =
let msg = hello "World"
putStrLn msg
You're missing a do:
main = do
let msg = hello "World"
putStrLn msg
You'll also want to export your main:
module Main ( main ) where
Since this is the main module, there is no need to export hello.
You're missing a in:
main = let msg = hello "World" in putStrLn msg
Related
I compiled the following program
-- Alice.hs
main = do
putStrLn "Hello"
l <- getLine
putStrLn $ "you said " ++ l
I want to communicate with Alice in another program: Bob.hs. My failed attempt is:
-- Bob.hs
import System.IO (hGetLine, hPutStrLn)
import System.Process (runInteractiveProcess)
main = do
(hin, hout, herr, ph) <- runInteractiveProcess "./Alice" [] Nothing Nothing
hello <- hGetLine hout
putStrLn hello
hPutStrLn hin "something"
reply <- hGetLine hout
putStrLn reply
Bob gets stuck before Hello is printed.
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 a newbie in Haskell and I'm reading "Learn You a Haskell for Great Good!".
An expression that defines with a "name" and a "space", followed by "parameters" could be used as functions.
Consider the following code:
doubleMe = 2
this code actually follows the rule above, so we could see it as a function. but it really seems like an assign operations in java or c++.
So, How to understand the variable in Haskell?
At the top level of a program, name = expression is a definition. It creates a variable, in the sense of a mathematical variable—just a name for some expression. It can be a definition of a value:
two :: Int
two = 2
Or a definition of a function:
twice :: Int -> Int
twice x = x * two
A definition refers to a function if its type has a function arrow ->.
In a do block or GHCi, let name = expression is a local definition.
main :: IO ()
main = do
let greet name = "Hello, " ++ name ++ "!"
putStrLn (greet "world")
Finally, there is another use of the let keyword: let name = expression1 in expression2. This creates a variable local to a single expression:
length (let x = "hello" in x ++ x) == 10
Be aware that let takes a block of bindings, so it’s subject to the layout rules like other layout keywords, such as do, where, of as in case…of, and so on:
main :: IO ()
main = do
-- Bindings must be aligned past the start column.
-- ↓
let greeting name = "Hello, " ++ name ++ "!"
parting name = "Goodbye, " ++ name ++ "!"
putStrLn (greeting "world")
putStrLn (parting "world")
length $ let x = "hello"
y = "goodbye"
in x ++ y
As with other layout keywords, can instead put a newline and a fixed amount of indentation after let, and then not worry about alignment:
main = do -- ← newline+indent
let -- ← newline+indent
greeting name = …
parting name = …
…
length $ let
x = "hello"
y = "goodbye"
in x ++ y
Or you can always include explicit curly braces and semicolons:
main :: IO ();
main = do {
let {
greeting name = "Hello, " ++ name ++ "!";
parting name = "Goodbye, " ++ name ++ "!";
};
putStrLn (greeting "world");
putStrLn (parting "world");
};
length $ let {
x = "hello";
y = "goodbye";
} in x ++ y
I know this works:
do name <- getLine; let nameTag = "Hello, my name is " ++ name in putStrLn nameTag
As well as this piece of code when loaded into GHCI:
hey = do
name <- getLine
let nameTag = "Hello, my name is " ++ name
putStrLn nameTag
But this does not work:
do name <- getLine; let nameTag = "Hello, my name is " ++ name; putStrLn nameTag
giving the following error message:
<interactive>:142:82:
parse error (possibly incorrect indentation or mismatched brackets)
Why doesn't it work? Can I make it work? If yes, then how?
Yes, you can use braces around the let binding(s) to disambiguate the parsing:
do name <- getLine; let { nameTag = "Hello, my name is " ++ name }; putStrLn nameTag
To complement the answer by McKenna, the error can be explained as follows: compare these two lines
do name <- getLine; let name1 = "One"; putStrLn name1
do name <- getLine; let name1 = "One"; name2 = "Two"; putStrLn name1
A human reader can see that they actually mean
do { name <- getLine; let { name1 = "One" } ; putStrLn name1 }
do { name <- getLine; let { name1 = "One"; name2 = "Two" }; putStrLn name1 }
but the parser is not that smart.
When the Haskell parser sees the common code portion
do name <- getLine; let name1 = "One";
-- ^ --
it has to decide whether the last ; belongs to the do level (as in the first case above), or to the let level (second case). It turns out that it chooses let, and fails later on.
I was playing around with a simple program in Haskell:
hello :: String -> String
hello s = "Hello, " ++ (trim s) ++ "!\n"
trim :: String -> String
trim [] = []
trim s = head $ words s
main :: IO()
main = do putStr "\nPlease enter your name: "
name <- getLine
hstring <- return $ hello name
putStr hstring
This is the output I am expecting:
Please enter your name: John Doe
Hello, John!
This works as expected when I load the program into ghci. However when I compile the program using
ghc -o hello.exe hello.hs
it starts, waits for input, and then prints both prompts at the same time:
John Doe
Please enter your name: Hello, John!
Why is the behavior different between the interactive environment and compiler, and how can I make the compiler do what I want?
Thanks in advance for the help!
This is something of an FAQ. Your lines are being buffered. Use:
import System.IO
main = do
hSetBuffering stdout NoBuffering
...
Also, your code is a bit... unique. For example, you say:
hstring <- return $ hello name
putStr hstring
When you could do:
let hstring = hello name
putStr hstring
or just:
putStr $ hello name