Что эквивалентно этому коду Python в Hasekell?

Я пытаюсь сделать приведенный ниже код Haskell равным коду Python, но он не работает, и я не могу обнаружить ошибку? Может ли кто-нибудь заметить ошибку? Вывод Python - это то, что я хочу

def balanceList(lst):
    length = len(lst)
    if length<3:
        return lst
    else:
        middle=length//2
        return [lst[middle]] + balance(lst[middle+1:] + balance(lst[:middle]))

print( balanceList(list(range(1,10))) )
# [5, 3, 8, 2, 7, 4, 9, 6, 1]
balanceList :: [a] -> [a]
balanceList lst
  | len < 3 = lst
  | otherwise = [lst !! middle] ++ balanceList (drop (middle+1) lst) ++ balanceList (take (middle) lst) 
    where len = length lst; middle = len `div` 2

-- >>> balanceList [1..9]
-- [5,8,9,6,7,3,4,1,2]

Вы уверены, что версия Python верна? Вы пишете balance(lst[middle+1:] + balance(lst[:middle])), но balance(lst[middle+1:]) + balance(lst[:middle]) кажется более естественным желанием.

amalloy 03.04.2023 13:08

Не беспокойтесь о смысле. Но да, скобки, где проблема...

tturbo 03.04.2023 13:39
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
75
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это проблема со скобками:

balanceList :: [a] -> [a]
balanceList lst
  | len < 3 = lst
  | otherwise = [lst !! middle] ++ balanceList (drop (middle+1) lst ++ balanceList (take (middle) lst))
    where len = length lst
          middle = len `div` 2

Здесь мы таким образом уравновешиваем первую часть, добавляем последнюю часть и снова уравновешиваем. Но неясно, было ли это намерением в Python.

Но использование length не очень похоже на Haskell. Вы можете разделить список на три с помощью рекурсии:

splitMiddle :: [a] -> ([a], a, [a])
splitMiddle ls = go ls ls
  where go [] (x:xs) = ([], x, xs)
        go [_] ~(x:xs) = ([], x, xs)
        go (_:_:ys) ~(x:xs) = let ~(b, m, a) = go ys xs in (x:b, m, a)

или с NonEmpty:

import Data.List.NonEmpty(NonEmpty((:|)))

splitMiddle :: NonEmpty a -> ([a], a, [a])
splitMiddle (x :| xs) = go (x:xs) x xs
  where go [] x xs = ([], x, xs)
        go [_] x xs = ([], x, xs)
        go (_:_:ys) x ~(x1:xs) = let ~(b, m, a) = go ys x1 xs in (x:b, m, a)

Затем мы можем использовать это для разделения и слияния:

balanceList :: [a] -> [a]
balanceList lst@(_:_:_:_) = m : balanceList (a ++ balanceList b)
  where (b, m, a) = splitMiddle lst
balanceList lst = lst

Не уверен, что предпочитаю splitMiddlelength+splitAt, тем более, что он не тотальный.

leftaroundabout 03.04.2023 13:22

Да скобки! Как плохо я этого не видел :(

tturbo 03.04.2023 13:37

@leftaroundabout: Я думаю, что lst!!middle является проблемной частью. splitMiddle, вероятно, должен работать с NonEmpty.

Willem Van Onsem 03.04.2023 14:30

Ага, но тогда еще и в NonEmpty нужно конвертировать в balanceList, это довольно неудобно. Я бы использовал balanceList lst = case splitAt (length lst`div`2) lst of {(l,m:r) -> ...}

leftaroundabout 03.04.2023 14:40

Другие вопросы по теме