Если бы я использовал 2-кортеж, что бы я комбинировал?
Это ключевой вопрос, стоящий за парадигмой передачи состояний в функциональном программировании, который также был задан Государственной монадой.Мы не будем иметь дело с последним здесь, но, возможно, используем первое.
Но перед этим, нам действительно нужно сгенерировать все числа в списке, а затем обработать этот список?Разве мы не знаем заранее с какими числами мы будем работать?
Конечно, мы знаем, потому что дерево, которое мы строим, полностью сбалансировано и полностью заполнено.
Итак, если у нас есть такая функция, как
-- build2 (depth, startNum)
build2 :: (Int, Int) -> Tree Int
, мы можем использовать ее точно так же , чтобы построить обе половины , например, build [0..14]
tree:
build [0..14] == build2 (4,0) == Node (build2 (3,0)) 7 (build2 (3,8))
Правильно?
Но если мы не хотим связываться с прямыми вычислениями всех участвующих чисел, мы могли бы организовать вышеупомянутую передачу состояний с помощьюПоверните к интерфейсу build2
:
-- depth, startNum tree, nextNum
build3 :: (Int, Int) -> (Tree Int, Int)
и используйте его как
build :: Int -> Tree Int -- correct!
build depth = build3 (depth, 0) -- intentionally incorrect
build3 :: (Int, Int) -> (Tree Int, Int) -- correct!
build3 (depth, start) = Node lt n rt -- intentionally incorrect
where
(lt, n) = build3 (depth-1, start) -- n is returned
(rt, m) = build3 (depth-1, n+1) -- and used, next
Вам нужно настроить выше, чтобы соединить все части вместе ( следуйтетипы! ), конечно, реализуя недостающие фрагменты и заботясь о угловых / базовых случаях.
Сформулировать это как развернутое будет следующим шагом.