Я не эксперт в Haskell, но это самый простой способ, который я могу придумать для решения этой проблемы, не предполагающего использования каких-либо других внешних функций.
concatDigits :: [Int] -> Int
concatDigits [] = 0
concatDigits xs = concatReversed (reverseDigits xs) 1
reverseDigits :: [Int] -> [Int]
reverseDigits [] = []
reverseDigits (x:xs) = (reverseDigits xs) ++ [x]
concatReversed :: [Int] -> Int -> Int
concatReversed [] d = 0
concatReversed (x:xs) d = (x*d) + concatReversed xs (d*10)
Как видите, я предположил, что вы пытаетесь составить список цифр. Если по какой-либо причине это не ваш случай, я уверен, что это не сработает. (
В моем решении, прежде всего, я определил функцию с именем reverseDigits
, которая переворачивает исходный список. Например, [1,2,3] - [3,2,1]
После этого я использую функцию concatReversed
, которая принимает список цифр и число d, которое является результатом десятикратного деления первой цифры на позиции списка. Если список пуст, он возвращает 0, а если нет, то возвращает первую цифру в списке раз d, плюс вызов concatReversed
, передающий остальную часть списка, и d раз 10.
Надеюсь, код говорит сам за себя, потому что я думаю, что мое плохое английское объяснение не очень помогло.
Редактировать
Спустя долгое время, я вижу, что мое решение очень грязное, так как требует перевернуть список, чтобы иметь возможность умножать каждую цифру на 10, увеличивая индекс цифры в списке, справа налево. Теперь, зная кортежи, я вижу, что гораздо лучший подход - иметь функцию, которая получает как накопленную преобразованную часть, так и остаток списка, поэтому при каждом вызове функция умножает накопленную часть на 10, а затем добавляет текущую цифру.
concatDigits :: [Int] -> Int
concatDigits xs = aggregate (xs, 0)
where aggregate :: ([Int], Int) -> Int
aggregate ([], acc) = acc
aggregate (x:xs, acc) = aggregate (xs, (acc * 10 + x))