问题1: 我有一个树类型的定义:
data Tree a = Node a (Tree a) (Tree a) |Empty
使用Show类型类实现show函数。像节点10一样的树(节点20空(节点6) 空空))(节点30空空))应显示为(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 :(得分:2)
您可以查看如何为Functor
here实施Tree
个实例。
如果某个类型是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
,然后在遍历树时以某种顺序连接它。
答案 1 :(得分: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
,因为它应该产生可以重建输入的输出......