7

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")
2
  • To add to @chi's answer, the code you've written is more-or-less correct Haskell syntax, but things like loop and while aren't built in. Haskell doesn't actually have do-while loops, it has recursion that you can use to implement do-while loops. Haskell doesn't actually have loops at all, just recursion, you'll have to learn how to re-implement features from imperative languages that you're used instead. Commented Feb 25, 2016 at 22:35
  • @bheklilr I guess gallais is right in their comment below, though: the above code seems to be adapted from the Control.Monad.LoopWhile docs. Commented Feb 25, 2016 at 22:39

2 Answers 2

15

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!"
Sign up to request clarification or add additional context in comments.

3 Comments

I'm guessing OP is trying to use loop-while (see the similarity with the code excerpts). Seeing the list of imports would help.
@gallais Interesting, I did not know of that... Still, I wonder if the OP really wants to use that library, or just wants to achieve the same effect. For a beginner, I'd suggest to learn the basic way first.
Instead of writing let loop = ...; loop, I like to write fix $ \loop -> .... Of course this is purely stylistic.
3

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");
    })        

3 Comments

If we define a custom helper function loop, I'd be temped to inline the definition of action and directly write loop $ do ....
but there is no problem... (i think so) please check edit in the answer
Yes, both ways are correct. The second one is nicer, at least for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.