Haskell:如何使用“派生秀”和仿函数?

时间:2014-02-13 05:33:27

标签: haskell

问题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? (我如何实现上面的函数使用函子?)

2 个答案:

答案 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,因为它应该产生可以重建输入的输出......

http://codepad.org/CDM1v2AY