Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 读取int';他在哈斯克尔_String_Haskell_Int - Fatal编程技术网

String 读取int';他在哈斯克尔

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

我一直在研究Haskell,更具体地说是
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

但是这个函数签名和我写的不同,不是吗?是的,但是用它来构建签名很简单@dcarou
takeWhile
可以使用
读取
-
fmap fst省略。海德梅。阅读。dropWhile(不是.isDigit)
(或者
fst.head.reads.dropWhile(不是.isDigit)
用于“标准”抛出版本)。也可以想象这样做
getNumber=asum。也许是地图。words
,具体取决于格式的规格。为什么需要较旧的外部软件包才能获取
readMay
?只需使用基本库中的
Text.Read.readMaybe
Int->Bool
的作用是什么?
getNumber
显然是一个交互式函数(在满足谓词的一次出现之前询问数字)?否则,它不应该有这个
IO
签名。顺便说一句,这个名字在这种情况下并不好,最好实际地叫它
askForNumber
-无论如何,这个函数看起来肯定不是一个可以用来从文本中提取内容的工具。
getNumber = listToMaybe . readMany