Извлеките текст между скобками

#haskell

Вопрос:

Я пытаюсь извлечь текст между скобками и в идеале получить список строк с содержимым скобок. Пример

 "ab(cde)fgh(ij)k" -> ["cde", "ij"]
 
 combine :: [a] -> [a] ->[[a]]
combine x y = [x, y]

extract x =
  combine y (extract (drop (length z) x))
  where z = takeWhile (/= ')') x
        y = dropWhile (/= '(') z
 

Я получаю эту ошибку:

 Couldn't match type '[Char]' with `Char'
    Expected type: [Char] -> [Char]
      Actual type: [Char] -> [[Char]]
 

Комментарии:

1. И что же идет не так? Из первого прочтения я предполагаю, что компилятор выдает ошибку типа. Если да, то какие части ошибки вы понимаете? Какие части вас смущают?

2. @DanielWagner Это ошибка типа. Одна из функций ожидает строку, но получает символ или наоборот. Я понятия не имею, кто это.

3. Вот подсказка: когда вы получаете ошибку, которую не понимаете, обычно полезно опубликовать текст этой ошибки в своем вопросе, чтобы люди, отвечающие на него, могли видеть, что пошло не так.

Ответ №1:

В вашем коде есть несколько проблем, но я надеюсь, что понял идею этого.

Сначала combine — если вы смотрите, как вы его используете: он должен вернуть то, что ваш extract доход (на вашем примере есть список String ), а второй параметр того же типа (как в результате рекурсивного extract ) — поэтому он должен иметь тип (или тип можно объединить с) String -> [String] -> [String] — глядя на то, что он должен делать это очень просто минусы в список ( : оператора).

Затем вы смешали x,y,z так, как, я думаю, вы на самом деле не хотели — вы объединяетесь с y , но y , кажется, это часть первой ( , которую вы найдете, — но вы хотите собрать части внутри (..) — аналогично тому, как вы определяете и используете z .

Наконец-то исправлено, что ваш код будет работать, но вы ( тоже будете собирать.

Эта версия исправляет все это для вас:

 extract :: String -> [String]
extract txt 
  | null begin = []
  | otherwise = part : extract rest
  where 
    begin = dropWhile (/= '(') txt
    after = tail begin
    part = takeWhile (/= ')') after
    rest = drop (length part   1) after
 

обратите внимание, что проблема все еще существует (попробуйте "ab(cde)fgh(ij)k(hmmmm" и посмотрите, что произойдет) — я уверен, что вы можете исправить это сами прямо сейчас.