tl;dr Вот ваша функция. Но я рекомендую читать дальше, чтобы увидеть, как я пришел к этому, чтобы вы могли разобраться в мыслительном процессе.
newbmap :: (a->b)-> Newb a -> Newb b
newbmap f = foldNewb (Leaf . f) Node
Вы довольно близки, и вы правильно используете foldNewb
, но вы слишком много обдумываете.
Во-первых, вы не можете назвать функцию Newbmap
. Заглавные имена зарезервированы для типов. Итак, мы назовем его newbmap
. Теперь foldNewb
уже обрабатывает оба случая Leaf
и Node
, поэтому нам вообще не нужно сопоставлять шаблоны в newbmap
. Фактически, ваш первый случай newbmap
делает именно то, что в любом случае сделал бы foldNewb
, так что давайте просто рассмотрим второй случай.
newbmap :: (a->b)-> Newb a -> Newb b
newbmap f (Node a) = (Node (foldNewb f concat a))
Мы хотим свернуть нашу структуру данных. В частности, мы хотим, чтобы наш вызов fold полностью создавал новую структуру данных. Нам не следует явно использовать Node
в конце, так как, опять же, foldNewb
уже работает за нас.
newbmap :: (a->b)-> Newb a -> Newb b
newbmap f a = foldNewb f concat a
Теперь в первом случае нам нужна функция a -> Newb b
(поскольку результат будет иметь тип Newb b
). Вы прошли f :: a -> b
, что очень близко к тому, что вы хотите. Нам просто нужно составить его с помощью функции b -> Newb b
, а Leaf
сделает именно это.
newbmap :: (a->b)-> Newb a -> Newb b
newbmap f a = foldNewb (Leaf . f) concat a
В качестве второго аргумента вам нужно [Newb b] -> Newb b
, что опять же очень легко сделать с помощью Node
.
newbmap :: (a->b)-> Newb a -> Newb b
newbmap f a = foldNewb (Leaf . f) Node a
И (хотя это не имеет значения) мы можем без указания последнего аргумента.
newbmap :: (a->b)-> Newb a -> Newb b
newbmap f = foldNewb (Leaf . f) Node
Итак, есть работающая функция newbmap
. Теперь, что касается того, как я пришел ко всем этим типам, если вы используете GHC, есть очень полезная функция под названием отверстия для типов, которую вы можете использовать, чтобы определить, какие типы вам нужны. Итак (и я сделал именно это при отладке вашей функции), если вы пишете
newbmap :: (a->b)-> Newb a -> Newb b
newbmap f = foldNewb _1 _2
тогда вы получите очень конкретные сообщения GHC, сообщающие вам _1 :: a -> Newb b
и _2 :: [Newb b] -> Newb b
. Тогда ваша задача состоит в том, чтобы просто найти функции с этими конкретными типами. И здесь я придумал Leaf . f
и Node
.
person
Silvio Mayolo
schedule
02.08.2018