Pergunta

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.

Foi útil?

Solução

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top