Haskell hello world won't compile - haskell

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

How to interact with process in haskell

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.

Menu option issue [duplicate]

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)

'let' and variables in Haskell

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

HASKELL --- Using "let" within a "do" syntax in GHCI

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.

Haskell do syntax and I/O

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

Resources