Kot*_*kot 2 io haskell functional-programming
Haskell中是否有像Pascal中的ReadLn这样的内置函数?
我想要这样的smth:
?> 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.
Run Code Online (Sandbox Code Playgroud)
你可以用它来解决这个问题 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
Run Code Online (Sandbox Code Playgroud)
它可以根据需要进行有效输入
? 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)
Run Code Online (Sandbox Code Playgroud)
然而,它并不完美,因为它无法区分不完整的解析和不可能的解析:
? pascalReadLn :: IO (Int, Int, Int, Int)
foo bar
1
2
3
4
... will go forever
Run Code Online (Sandbox Code Playgroud)
自定义实现(沿着相同的行ArgumentTuple)可以通过区分两种故障情况来解决这个问题,例如:
data ParseResult a = Success a | Incomplete (String -> ParseResult a) | Impossible
class LineTuple a where
parseLine :: String -> ParseResult a
Run Code Online (Sandbox Code Playgroud)