Reputation: 770
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.
Upvotes: 2
Views: 104
Reputation: 116139
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.
Upvotes: 7