Question

At the moment, I have this code in and around main:

import Control.Monad
import Control.Applicative

binSearch :: Ord a => [a] -> a -> Maybe Int

main = do
    xs <- lines <$> readFile "Cars1.txt"
    x <- getLine <* putStr "Registration: "  -- Right?
    putStrLn $ case binSearch xs x of
                    Just n -> "Found at position " ++ show n
                    Nothing -> "Not found"

My hope is for “Registration: ” to be printed, then for the program to wait for the input to x. Does what I've written imply that that will be the case? Do I need the <*, or will putting the putStr expression on the line above make things work as well?

PS: I know I have to convert binSearch to work with arrays rather than lists (otherwise it's probably not worth doing a binary search), but that's a problem for another day.

Was it helpful?

Solution

The line

x <- getLine <* putStr "Registration: "

orders the IO actions left-to-right: first a line is taken as input, then the message is printed, and finally variable x is bound to the result of getLine.

Do I need the <*, or will putting the putStr expression on the line above make things work as well?

If you want the message to precede the input, you have to put the putStr on the line above, as follows:

main :: IO ()
main = do
    xs <- lines <$> readFile "Cars1.txt"
    putStr "Registration: "
    x <- getLine
    putStrLn $ case binSearch xs x of
                    Just n  -> "Found at position " ++ show n
                    Nothing -> "Not found"

Alternatively,

    x <- putStr "Registration: " *> getLine

or

    x <- putStr "Registration: " >> getLine

would work, but they are less readable.

Finally, since you added the lazy-evaluation tag, let me add that your question is actually not about laziness, but about how the operator <* is defined, and in particular about the order in which it sequences the IO actions.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top