String 读取int';他在哈斯克尔
我一直在研究Haskell,更具体地说是String 读取int';他在哈斯克尔,string,haskell,int,String,Haskell,Int,我一直在研究Haskell,更具体地说是IOmonad,我想知道如何做到以下几点: 假设我有这个函数签名: getNumber :: String −> (Int −> Bool) −> IO Int 本文: “我叫加里,今年21岁” 如果我只想读这个句子中的数字“21”,我该如何在Haskell中读呢 这可以通过列表处理操作完成 import Text.Read import Data.Char getNumber :: String -> Maybe Int
IO
monad,我想知道如何做到以下几点:
假设我有这个函数签名:
getNumber :: String −> (Int −> Bool) −> IO Int
本文:
“我叫加里,今年21岁”
如果我只想读这个句子中的数字“21”,我该如何在Haskell中读呢 这可以通过列表处理操作完成
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
但是,如果您想进行任何严肃的解析,我建议使用Parsec或Attoparsec,它们都非常易于使用,而且更加健壮。这里有一个函数,它可以从
字符串中提取多个可读的内容:
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
但是这个函数签名和我写的不同,不是吗?是的,但是用它来构建签名很简单@dcaroutakeWhile
可以使用读取
-fmap fst省略。海德梅。阅读。dropWhile(不是.isDigit)
(或者fst.head.reads.dropWhile(不是.isDigit)
用于“标准”抛出版本)。也可以想象这样做getNumber=asum。也许是地图。words
,具体取决于格式的规格。为什么需要较旧的外部软件包才能获取readMay
?只需使用基本库中的Text.Read.readMaybe
。Int->Bool
的作用是什么?getNumber
显然是一个交互式函数(在满足谓词的一次出现之前询问数字)?否则,它不应该有这个IO
签名。顺便说一句,这个名字在这种情况下并不好,最好实际地叫它askForNumber
-无论如何,这个函数看起来肯定不是一个可以用来从文本中提取内容的工具。
getNumber = listToMaybe . readMany