在此示例中,我可以确定IO操作的顺序吗?

时间:2014-05-12 22:21:12

标签: haskell io lazy-evaluation

目前,我在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"

我希望打印“Registration:”,然后让程序等待x的输入。我所写的内容是否意味着会出现这种情况?我是否需要<*,或者将putStr表达式放在上面的行中以使其工作正常?

PS:我知道我必须将binSearch转换为使用数组而不是列表(否则它可能不值得进行二进制搜索),但这是另一天的问题。

1 个答案:

答案 0 :(得分:7)

该行

x <- getLine <* putStr "Registration: "

从左到右命令IO操作:首先将一行作为输入,然后打印消息,最后将变量x绑定到getLine的结果。

  

我是否需要&lt; *,或者将putStr表达式放在行上   以上使事情也有效?

如果您希望消息位于输入之前,则必须将putStr放在上面的行中,如下所示:

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"

可替换地,

    x <- putStr "Registration: " *> getLine

    x <- putStr "Registration: " >> getLine

会起作用,但它们的可读性较差。

最后,由于您添加了 lazy-evaluation 标记,让我补充一点,您的问题实际上不是关于懒惰,而是关于如何定义运算符<*,特别是关于它对IO动作进行排序的顺序。