Что касается более элегантных [...] решений?
Это прекрасно. Все другие решения, не использующие вспомогательные функции, будут выглядеть примерно одинаково. Единственное, что я хотел бы изменить это выравнивание =
с и именами x
и y
в l
и r
(со ссылкой на левую и правую ветви):
instance Functor Tree where
fmap _ Empty = Empty
fmap f (Node a l r) = Node (f a) (fmap f l) (fmap f r)
Впрочем, это мое личное мнение. Давайте перейдем к главному вопросу, fmap
«s типа:
Вторая проблема в том, что преподаватель написал подпись: fmap :: (a -> b) -> f a -> f b
[...]
Прежде всего, подпись лектора является несколько неправильно. полная подпись fmap
«s является
fmap :: Functor f => (a -> b) -> f a -> f b
Ограничение Functor f
важно. Он ограничивает использование fmap
экземплярами Functor
. Теперь это не проблема, с которой вы столкнулись:
для меня это (a->b) -> Tree a -> Tree b
, но компилятор ghci не принимается. Где смысл?
Ах, вы пытались определить тип подписи для fmap
в экземпляре Functor Tree
, верно?
instance Functor Tree where
fmap :: (a -> b) -> Tree a -> Tree b
fmap = ...
Ну, это недопустимо. В конце концов, fmap
тип не(a -> b) -> Tree a -> Tree b
, но более общий один выше. Это несколько —, но не совсем — похоже на использование двух подписей типа для одного связывания:
foo :: Eq a => a -> a -> Bool
foo :: () ->() -> Bool
Это не разрешено ни. Обратите внимание, что вы можете включить подписи экземпляров with an extension, если вы действительно этого хотите.Если вы просто хотите, чтобы сделать это для документации, комментарий может быть использован вместо -XInstanceSigs
:
instance Functor Tree where
-- fmap :: (a -> b) -> Tree a -> Tree b
fmap = ...
TL; DR: тип fmap
«s дается это декларация в class Functor
, он уже указан ваш выбор от f
в определении instance
.
Если вы включите расширение DeriveFunctor в GHC, вы можете получить экземпляр Functor для компилятора, если вы измените свое определение на 'data Tree a = Empty | Узел a (Дерево a) (Дерево a), получающее (Functor) '. Ваша реализация довольно стандартная, поэтому я сомневаюсь, что вы можете сделать ее более «элегантной». – Lee
Как насчет подписи? –
Я не понимаю вашу проблему с подписями, тип 'fmap' is' (a -> b) -> f a -> fb', который есть у вас там, где 'f' является' Tree'. – Lee