Подобные функции применяются к вложенному списку в Haskell - PullRequest
1 голос
/ 30 марта 2020

Вот проблема, с которой я столкнулся. У меня есть некоторые функции, которые похожи по своему телу (с небольшой разницей), но у них есть подписи.

flatB :: [[String]] -> [[String]]
flatB []  = []
flatB [x] = [x]
flatB (a : b : xs) | isDigit (head n) = replicate (read n :: Int) a ++ flatB xs
                   | otherwise = a : flatB (b : xs)
    where n = head b

flatC :: [String] -> [String]
flatC []  = []
flatC [x] = [x]
flatC (a : b : xs) | isDigit (head b) = replicate (read b :: Int) a ++ flatC xs
                   | otherwise = a : flatC (b : xs)

Я ожидаю, что функция сделает следующее:

> flatC ["a","2","b"]
["a","a","b"]

> flatB [["a","b"],["2"]]
[["a","b"],["a","b"]]

Код выше работает. Но мне интересно, есть ли более простой способ добиться этого?

Я думаю, что создание класса типов может быть способом, но я не знаю, как это сделать.

1 Ответ

3 голосов
/ 30 марта 2020

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

import Text.Read (readMaybe)

flat :: (a -> Maybe Int) -> [a] -> [a]
flat _ []  = []
flat _ [x] = [x]
flat readElem (a : b : xs)
  | Just n <- readElem b = replicate n a ++ flat readElem xs
  | otherwise = a : flat readElem (b : xs)

flatB :: [[String]] -> [[String]]
flatB = flat readHead
  where
    readHead [] = Nothing
    readHead (n : _) = readMaybe n

flatC :: [String] -> [String]
flatC = flat readMaybe
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...