Меня интересует способ более высокого порядка (схема рекурсии) для написания рекурсивного кода, в котором могут быть зависимости между рекурсивными вызовами.
В качестве упрощенного примера рассмотрим функцию, которая проходит по дереву целых чисел, проверяя, меньше ли сумма некоторого значения. Мы могли бы просуммировать все дерево и сравнить его с максимальным. В качестве альтернативы мы могли бы сохранить текущую сумму и закоротить, как только мы превысим максимум:
data Tree = Leaf Nat | Node Tree Tree
sumLT :: Nat -> Tree -> Bool
sumLT max t = sumLT' max t > 0
sumLT' :: Nat -> Tree -> Int
sumLT' max (Leaf n) = max - n
sumLT' max (Node l r) =
let max' = sumLT' max l
in if max' > 0 then sumLT' max' r else 0
Есть ли способ выразить эту идею — по сути, упорядоченный обход — с помощью схемы рекурсии? Меня интересует как можно более общее составление упорядоченных обходов, подобных этому.
В идеале я хотел бы написать обходы, в которых функция, свернутая (или развернутая) над структурой данных, определяет порядок обхода. Какую бы абстракцию я ни получил, я хотел бы также написать версию обхода sumLT'
в обратном порядке, где вместо этого мы идем справа налево:
sumLT'' :: Nat -> Tree -> Int
sumLT'' max (Leaf n) = max - n
sumLT'' max (Node l r) =
let max' = sumLT'' max r
in if max' > 0 then sumLT'' max' l else 0
sumLT'
не будет компилироваться. Пожалуйста, убедитесь, что код вашего примера действительно компилируется, если только ваш вопрос не касается того, почему код не компилируется. - person amalloy   schedule 29.01.2021Int
s может быть отрицательным. Вы хотели использоватьNatural
? Или предположить достаточно небольшое количество достаточно неотрицательныхInt
, чтобы они не переносились? - person dfeuer   schedule 29.01.2021Nat
и представим, что у нас есть средство доказательства теорем или что-то в этом роде. Пример (явно плохо продуманный) и вроде бы не относящийся к делу - я просто пытался придумать простой пример рекурсивного обхода, в котором есть зависимость между рекурсивными вызовами. - person trpnd   schedule 29.01.2021Foldable
илиMFoldable
для такого рода вещей, поскольку они выпекаются в понятии порядка.foldr
, безусловно, справится с этой задачей. - person dfeuer   schedule 29.01.2021Foldable
- это единственный вариант, который у меня есть до сих пор - в основном любопытно, предоставляют ли схемы рекурсии (или что-то еще) более общие параметры. До сих пор я подозреваю, что не может быть ничего более общего, поскольку весь смысл схем рекурсии и тому подобного заключается в абстрагировании рекурсивной структуры, но мне любопытно, есть ли что-то более общее, скрывающееся за всей теорией категорий. - person trpnd   schedule 29.01.2021any
изscanl
.scanl
на самом деле не в Traversable, но в основном это особый случай mapAccumL, который есть. В общем, если вы хотите проверить промежуточные результаты, вы можете отработать сканирование. - person David Fletcher   schedule 29.01.2021scan
все еще проходит в любом порядке, который определяет экземпляр Foldable, не так ли? В идеале я бы хотел, чтобы сама алгебра (функция складывалась) каким-то образом определяла порядок обхода - person trpnd   schedule 29.01.2021