Я это Data.Text
Как синтаксический анализ текста и извлекать целое
"Check: Find max among: 70, 102, 271, 40"
Как извлечь число из этого текста и применить функцию к ним?
Я это Data.Text
Как синтаксический анализ текста и извлекать целое
"Check: Find max among: 70, 102, 271, 40"
Как извлечь число из этого текста и применить функцию к ним?
Для 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
OP сказал «Data.Text». – dfeuer
@dfeuer: если человек может представить Data.Text без 'распаковки'. Полагает, что это справедливо только в эпоху до Google, но в любом случае ... –
@dfeuer: тогда вы теперь можете использовать другой ответ ...; P –
Этот пример кода показывает простой способ сделать это:
import Data.List
import Control.Monad
getLine >>= \line -> putStrLn $ show $ maximum $ (map read . words $ filter (/=',') $ line :: [Int])
Downvoter отмечает, что вопрос касается 'Text', а не' String'. – dfeuer
@vikingsteve: была та же проблема. Очень важно, конечно ... Особенно, если вы предоставляете несколько номеров ... –
Хорошо, спасибо. Будет ли «Data.Text.unpack» использоваться для работы со строковыми функциями, например. 'слова'? – vikingsteve
Вы можете использовать многие из 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
Вы * почти * получите upvote здесь. Остаются две проблемы: 1. Нет причин использовать 'signed', если вы отфильтровываете знаки. 2. Кажется, что намного больше Haskellian заменяет «либо (ошибка.show) fst' с 'fmap fst' и окончательной' map' с 'mapM' или' traverse'. – dfeuer
И (3), он не вычисляет максимум, который после всего вопроса о OP. –
@CommuSoft, хорошая точка. Это просто требует выполнения другой функции, чтобы сделать 'fmap maximum'. – dfeuer
Для различных эстетических соображений мне нравится этот подход:
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
как строка или 'IO' монада? –
его текст, который я получаю как параметр в запросе http получить – custosat
Итак, функция - это слово? Есть ли способ изолировать 'max', ... Каковы спецификации? –