在Haskell中是否存在像Pascal中的ReadLn这样的内置函数?
我想要像这样的人:
λ> pascalReadLn :: IO (Int, Int, Int, Int)
1 2
3
4
(1,2,3,4)
λ> pascalReadLn :: IO (Int, Int, Int, Int)
1 2 3 4
(1,2,3,4)
λ> pascalReadLn :: IO (Int, Int, Int, Int)
1
2
3
4
(1,2,3,4)
...
etc.
答案 0 :(得分:7)
你可以使用ReadArgs
import ReadArgs
pascalReadLn :: ArgumentTuple a => IO a
pascalReadLn = pascalReadLn' ""
where pascalReadLn' lines = do
line <- getLine
let lines' = lines ++ line
-- see if we've read enough to successfully parse the desired tuple
case parseArgsFrom (words lines') of
Nothing -> pascalReadLn' (lines' ++ "\n")
Just a -> return a
它可以根据需要进行有效输入
λ pascalReadLn :: IO (Int, Int, Int, Int)
1 2
3
4
(1,2,3,4)
λ pascalReadLn :: IO (Int, Int, Int, Int)
1 2 3 4
(1,2,3,4)
λ pascalReadLn :: IO (Int, Int, Int, Int)
1
2
3
4
(1,2,3,4)
然而,它并不完美,因为它无法区分不完整的解析和不可能的解析:
λ pascalReadLn :: IO (Int, Int, Int, Int)
foo bar
1
2
3
4
... will go forever
自定义实现(与ArgumentTuple
相同)可以通过区分两种失败案例来解决这个问题,例如:
data ParseResult a = Success a | Incomplete (String -> ParseResult a) | Impossible
class LineTuple a where
parseLine :: String -> ParseResult a