Вы хотите, чтобы ваша карта применяла функцию к любой метке, которую несет ваше дерево. Это означает, что любое вхождение a
должно быть заменено вхождением на b
, используя функцию, заданную в качестве функции преобразования.
Для этого вам необходимо выяснить, что делать с каждым возможным конструктором Stree
. Теперь Null
легко - это не будет зависеть от a
. Хитрее то, что делать с Fork
. В Fork
есть один a
и еще два Stree
, так что вам нужны функции, которые принимают a -> b
и Stree a -> Stree b
. В первом случае вызов mapStree
дает вам функцию, а во втором mapStree f
имеет нужную подпись вызова (при частичном применении!).
Для foldStree
у вас есть некоторый тип накопления b
и ваш тип метки a
, а также функция накопления, которая принимает два значения типа b
и значение типа a
и создает b
, Это полезно, не в последнюю очередь потому, что эта функция накопления отражает то, что вы могли бы иметь в любой заданный Fork
в дереве: рекурсией вы можете предположить, что у вас есть результаты как слева, так и справа Stree
, и остается только объединить те, которые имеют значение a
в середине, чтобы дать новое значение b
для передачи рекурсии. Параметр b
для foldStree
предоставляет вам достаточно стандартного значения, чтобы все началось с получения значения для каждого листа.
Таким образом, ваш foldStree
также должен быть определен для возможных конструкторов: выбирая параметр для значения Null
, а затем для значения Fork
он должен быть преобразован в оба значения Stree
перед объединением всего с функцией объединения параметров.
Пожалуйста, уточните в комментариях, поможет ли это вам в достаточной степени справиться с проблемой: я (и многие другие здесь) могу уточнить, но надеюсь, что вы научитесь делать это, а не просто дадите свой код.