2014-02-13 3 views
0

Вопрос 1: У меня есть определение для типа дерева:Haskell: как использовать «получение шоу» и функтор?

data Tree a = Node a (Tree a) (Tree a) |Empty 

Используйте Показать класс типов для выполнения шоу-функции. Дерево вроде Node 10 (Node 20 Empty (Node 6 Empty Empty)) (Node 30 Empty Empty)) должно отображаться как (10 (20 x 6) 30). Таким образом, узел с двумя пустыми ветвями не должен быть заключен в скобки.

Мой код выглядит следующим образом:

data Tree a = Node a (Tree a) (Tree a) |Empty deriving (show) 
--input 
*Main>>Node 10 (Node 20 Empty (Node 6 Empty Empty)) (Node 30 Empty Empty)) 
--output 
*Main>>Node 10 (Node 20 Empty (Node 6 Empty Empty)) (Node 30 Empty Empty)) 

Есть ли способ, чтобы изменить его, пусть выход:

(10 (20 x 6) 30) 

Вопрос 2:

Используйте класс функтора для определения fmap для этого типа?
(Как я могу реализовать выше использования функции функтора?)

ответ

0

Конечно, вы бы реализовать Show:

instance Show a => Show (Tree a) where 
    show Empty = "()" 
    show (Node x Empty Empty) = show x 
    show (Node x Empty y) = "(" ++ show x ++ " x " ++ show y ++ ")" 
    show (Node x Empty y) = "(" ++ show x ++ " " ++ show y ++ " x)" 
    show (Node x y z) = "(" ++ show x ++ " " ++ show y ++ " " ++ show z ++ ")" 

Однако, это было бы немного злоупотребления Show, так как он должен производить вывод что можно восстановить вход ...

http://codepad.org/CDM1v2AY

+0

Ну, это результат, который может восстановить вход - между его двумя объектами и их представлениями есть взаимно однозначное отображение. Итак, все, что нужно, - это соответствующая реализация 'Read', правильно? – amalloy

+0

@amalloy: Ну, если какой-либо 'a' производит выходные данные с пробелами и без разделителей (например, по умолчанию для' получения Show'), это будет сложно ... Я полагаю, что в случае необходимости можно будет проверить их и в скобках , – Ryan

+0

Я имею в виду, вы будете использовать экземпляр 'Read' для' a', который решает вашу проблему, не так ли? И ваше возражение одинаково хорошо относится к экземпляру по умолчанию, создаваемому 'deriving Show', я думаю, поэтому это не должно быть проблемой. – amalloy

2

Вы можете увидеть, как реализовать Functor экземпляр для Treehere.

Если какой-либо тип является экземпляром класса Functor, это значит, что вы можете сопоставить его значение и сохранить его. (Используйте ссылку выше, чтобы узнать больше о Functor). Например, если у вас есть tree :: Tree Int с некоторыми значениями в каждом узле, то вы можете заменить их на символ 'A', используя fmap (\ _ -> 'A') tree. Результат будет Tree Char, но он по-прежнему Tree.

Чтобы распечатать определенное значение, его необходимо преобразовать в String. Преобразование tree :: Tree a в String производит String, но не Tree Int. Вот почему вы не можете использовать fmap для реализации такого преобразования.

Для этого вам необходимо пройти Tree a. Единственное, что вы можете сделать, просто использовать fmap, - это преобразовать все значения в String s, а затем объединить их в некотором порядке при обходе дерева.

Смежные вопросы