Как разбить список чисел на набор из списка всех чисел в Haskell - PullRequest
0 голосов
/ 24 октября 2018

Как мне разбить список в Haskell, например, "222 33244" на ["222", "33", "2", "444"] только с помощью рекурсии и функций на прелюдии?

Моя текущая попытка:

list xs
  |length xs == 0 = ""
  |otherwise = listSplit xs

 listSplit (x:xs)
  |x == head xs = x : ListSplitNext x xs
  |otherwise = x:[]

 listSplitNext a (x:xs)
  |a == x = a : listSplitNext x xs
  |otherwise = listSplit xs

Ответы [ 3 ]

0 голосов
/ 24 октября 2018

Если ваша цель - использовать очень мало предопределенных функций, это может дать вам несколько идей:

listSplit :: String -> [String]
listSplit xs =
  let (as, a) = foldr go ([], []) numbers
  in  a : as
 where
  isNumber x = x `elem` ['0'..'9']
  numbers    = filter isNumber xs

  go cur (res, []) = (res, [cur])
  go cur (res, lst@(a:_))
    | a == cur  = (res, a : lst)
    | otherwise = (lst : res, [cur])

Конечно, вы также можете заменить foldr на собственную рекурсию:

numberSplit :: String -> [String]
numberSplit xs =
  let numbers = filter (`elem` ['0'..'9']) xs
  in  listSplit numbers


listSplit :: Eq a => [a] -> [[a]]
listSplit =
  reverse . go [] []
 where
  go acc as [] = as : acc
  go acc [] (x:xs) = go acc [x] xs
  go acc as@(a:_) (x:xs)
    | a == x    = go acc (a : as) xs
    | otherwise = go (as : acc) [x] xs
0 голосов
/ 24 октября 2018

У меня был момент, чтобы реализовать это, но я думаю, что это то, что вы ищете.

listSplit s = go filtered
  where filtered = [c | c <- s, elem c ['0'..'9']]
        go [] = []
        go (x:xs) = (x : takeWhile (== x) xs) : (go $ dropWhile (== x) xs)
0 голосов
/ 24 октября 2018

Так как я не совсем понимаю ваш подход и ghci перечисляет 18 ошибок компиляции в вашем коде, я боюсь, что не смогу помочь вам с вашей попыткой найти решение.

Как указано вкомментарий, возможное решение было бы:

listSplit xs = listSplit' [] (filter (`elem` ['0'..'9']) xs)

listSplit' ws (x:xs) = listSplit' (ws ++ [x : takeWhile (==x) xs]) (dropWhile (==x) xs)
listSplit' ws [] = ws
  1. Фильтровать каждый элемент строки, который не является числом (Data.Char.isNumber сделал бы это тоже, но предпосылкадолжен был использовать только функции Prelude) и вызывать listSplit' в отфильтрованном списке.

  2. (ws ++ [x : takeWhile (==x) xs]) собирает все в xs, пока не достигнет буквы, которая не равна x, оборачивает это в список и добавляет к ws.

  3. (dropWhile (==x) xs) удаляет каждую букву в xs, пока не достигнет буквы, которая не равна x.

  4. Наконец, функция вызывает себя с обновленным ws и уменьшенным xs

  5. Если больше не осталось элементов,функция возвращает ws

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...