我有Data.Text
"Check: Find max among: 70, 102, 271, 40"
如何从此文本中提取数字并对其应用函数?
答案 0 :(得分:1)
您可以使用许多Haskell解析库来解析Text
类型,但是对于这样一个简单的示例,我只需将其分解为单词,过滤数字并进行转换。正如dfeuer指出的那样,Haskell的String
类型与其他答案使用的类型和您可能错误暗示的Text
类型之间存在很大差异。对于文本类型,操作看起来非常相似,但您没有Prelude read
操作:
import qualified Data.Text as T
import Data.Text (Text)
import Data.Char (isDigit)
import Data.Text.Read
myRead :: Text -> [Int]
myRead = map num -- Convert the remaining elements into Ints
. filter (not . T.null) -- Drop all empty words
. map (T.filter isDigit) -- Drop all non-digits in each word (including signs!)
. T.words -- Chop the string into words
num :: Text -> Int
num = either (error . show) fst -- Throw an exception if it wasn't a signed decimal
. signed decimal -- Read a signed decimal
答案 1 :(得分:0)
此代码示例显示了一种简单的方法:
import Data.List
import Control.Monad
getLine >>= \line -> putStrLn $ show $ maximum $ (map read . words $ filter (/=',') $ line :: [Int])
答案 2 :(得分:0)
出于各种美学原因,我喜欢这种方法:
import qualified Data.Text as T
import Data.Text.Read
import Data.Either
import Data.Char
import Data.Text.IO as T
readNums :: T.Text -> [Int]
readNums =
map fst . -- 5. extract the parsed numbers
snd . partitionEithers . -- 4. collect only the valid numbers
map decimal . -- 3. parse each substring as an number
filter (not . T.null) . -- 2. filter out empty strings (not necessary)
T.split (not . isDigit) -- 1. split on non-digits
答案 3 :(得分:0)
这是适用于Text
的单行解决方案。它将数字从Text
中拉到带有
sepCap
组合器,然后可以应用maximum
函数。
由于这是一个解析器,因此您可以将其扩展到比本示例更复杂的内容,例如实际从字符串的第一部分解析查询指令。
import Replace.Megaparsec
import Text.Megaparsec
import Text.Megaparsec.Char.Lexer
import Data.Either
import Data.Maybe
import qualified Data.Text as T
maximum $ rights $ fromJust $ parseMaybe (sepCap (decimal :: Parsec Void T.Text Int))
"Check: Find max among: 70, 102, 271, 40"
271
答案 4 :(得分:-2)
对于String
,您可以使用:
maximum . map (read) . filter (all isDigit) . map (filter ((/=) ',')) words
或者对于Text
,请使用:
import Prelude as P
import Data.Text as T
fString :: Text -> Integer
fString = maximum . P.map (read) . P.filter (all isDigit) . P.map (P.filter ((/=) ',')) . P.map (T.unpack) . T.words
然后,您可以编写main
函数来读取stdin
中的值。
main :: IO ()
main = do
x <- getLine
putStrLn $ show $ fString (pack x) --to demonstrate that it works with Data.Text