从控制台获取整数

时间:2014-06-11 22:06:06

标签: haskell input

有没有办法在Haskell中从控制台读取整数?我要求的东西非常像C ++的cin或Java的Scanner.nextInt()。

我的意思是,考虑到这个输入:

1 2 3
2 3
4 25 12 7
1

我应该能够全部阅读它们,而不是同时阅读它们(可能会阅读其中的4个,进行一些计算,然后阅读其余部分)忽略它们分开的事实。

3 个答案:

答案 0 :(得分:5)

最简单的解决方案可能是

getAll :: Read a => IO [a] 
getAll = fmap (fmap read . words) getContents

getInts :: IO [Int]
getInts = getAll

将所有输入读入单个列表。

答案 1 :(得分:1)

如果有疑问,请使用Parsec!(并非总是如此,而不是真的,但是谁在乎)

import Text.ParserCombinators.Parsec
import Text.Parsec.Numbers

value = do 
    spaces
    num <- parseFloat
    return num

line = many value

然后“冲洗并重复”,getLine直到你EOF。

注意:你可以在没有 Parsec的情况下使用read和朋友进行,但这种方式更易扩展,更适用于更复杂的语法。

答案 2 :(得分:0)

使用Parsec:

import Text.ParserCombinators.Parsec
import Text.Parsec.Numbers
import Control.Applicative ((*>), (<*))
line = spaces *> many1 (parseFloat <* spaces)
main = putStrLn "Enter numbers:" >> fmap (parse line "") getLine >>= print

运行它:

$ ghc parsenums.hs
$ ./parsenums
Enter numbers:
345 23 654 234
[345.0,23.0,654.0,234.0]

更多&#34;手册&#34;这样做的方法就像:

import Data.Char (isDigit, isSpace)

getInts :: String -> [Int]
getInts s = case span isDigit (dropWhile isSpace s) of
  ("", "") -> []
  ("", s) -> error $ "Invalid input: " ++ s
  (digits, rest) -> (read digits :: Int) : getInts rest

可以更清楚地看到它是如何工作的。事实上,这是一个完全从头开始的人:

getInts :: String -> [Int]
getInts s = case span isDigit (dropWhile isSpace s) of
  ("", "") -> []
  ("", s) -> error $ "Invalid input: " ++ s
  (digits, rest) -> strToInt digits : getInts rest

isDigit :: Char -> Bool
isDigit c = '0' <= c && c <= '9'

isSpace :: Char -> Bool
isSpace c = c `elem` " \t\n\r"

charToInt :: Char -> Int
charToInt c = fromEnum c - 48

strToInt :: String -> Int
strToInt s = go 0 s where
  go n [] = n
  go n (c:rest) = go (n * 10 + charToInt c) rest