Sebastian Paulsen
Sebastian Paulsen

Reputation: 89

How to use let inside if block inside a do notation in haskell

I'm getting an error with the following code:

main = do
    putStrLn "Enter parameter"
    parameter <- getLine
    if head parameter == "c" then
        let object = getObject parameter
        print object
    else
        putStrLn "Error, try again"
        main

The error I get is:

parse error on input `print'

when trying to print the object. If I instead try to print the value of the function without saving it with let it works just fine, but I need to save the object for later use.

How should the syntax be to make it work?

Also in the "else" part I get the following error:

The function `putStrLn' is applied to two arguments,
    but its type `String -> IO ()' has only one
    In the expression: putStrLn "Error" main

It thinks I try to run main as a parameter to putStrLn, but what I really want to do is first show the error and then run main again. How can I fix this?

Thanks in advance!

Upvotes: 4

Views: 3341

Answers (1)

Zpalmtree
Zpalmtree

Reputation: 1359

There's a few issues with your code.

Firstly, there's the parse error. There's two ways to fix this. One is by using a let .. in block, as @Lee points out.

let object = getObject parameter
in  print object

Alternatively, we can just start another do block in the else clause:

then do
   let object = getObject parameter
   print object

Secondly, you're comparing the head of a string, to another string:

head parameter == "c"

getLine returns a string, so the head of a string is a character. We can just change this to

head parameter == 'c'

And finally, you're trying to do two statements in one block, similar to before in your else clause:

else 
    putStrLn "Error, try again"
    main

If you want to chain together multiple statements, we have to use a do block, as before:

else do
    putStrLn "Error, try again"
    main

Putting it all together:

main = do
    putStrLn "Enter parameter"
    parameter <- getLine
    if head parameter == 'c' then do
        let object = getObject parameter
        print object
    else do
        putStrLn "Error, try again"
        main

Upvotes: 5

Related Questions