在Haskell中读取int

时间:2013-11-24 16:09:41

标签: string haskell int

我一直在研究Haskell,更具体地说是IO monad,我想知道如何做到以下几点:

假设我有这个函数签名:

getNumber :: String −> (Int −> Bool) −> IO Int  

和本文:

“我的名字是加里,我才21岁”

如果我只想从这句话中读出数字“21”,我将如何在Haskell中完成?

2 个答案:

答案 0 :(得分:1)

这可以通过列表处理操作来完成,

import Text.Read
import Data.Char

getNumber :: String -> Maybe Int
getNumber = readMaybe . takeWhile isDigit . dropWhile (not . isDigit)

现在使用它来构建你的功能要容易得多。目前尚不清楚Int -> Bool的用途,或者,如果您已经有字符串,为什么需要IO。要获得功能,您可以执行类似

的操作
yourFunc :: (Int -> Bool) -> IO Int
yourFunc f = do
   r <- fmap getNumber getLine
   case r of
     Nothing -> putStrLn "Please enter a number" >> yourFunc f
     Just x | f x       -> return x
            | otherwise -> putStrLn "Doesn't satisfy predicate" >> yourFunc f

用法:

> yourFunc even
  I am a person
  Please enter a number
  I am 21
  Doesn't satisfy predicate
  I am 22
  22

但是如果你想进行任何严肃的解析,我会推荐Parsec或Attoparsec,它们都非常易于使用且更加强大。

答案 1 :(得分:1)

这是一个从String

中提取多个可读内容的函数
import Data.List (unfoldr, tails)
import Data.Maybe (listToMaybe)

readMany :: Read a => String -> [a]
readMany = unfoldr $ listToMaybe . concatMap reads . tails

例如:

> readMany "I like the numbers 7, 11, and 42." :: [Int]
[7,11,42]

您可以轻松地将此专门化为jozefg的函数getNumber

justOne :: [a] -> Maybe a
justOne [x] = Just x
justOne _   = Nothing

getNumber :: String -> Maybe Int
getNumber = justOne . readMany

或者你可以稍微宽松一点,并在指定多个时选择第一个数字:

getNumber = listToMaybe . readMany