Haskell 哈斯克尔:如何使用;“衍生秀”;函子呢?
问题1: 我有树类型的定义:Haskell 哈斯克尔:如何使用;“衍生秀”;函子呢?,haskell,Haskell,问题1: 我有树类型的定义: data Tree a = Node a (Tree a) (Tree a) |Empty 使用ShowTypeClass实现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
data Tree a = Node a (Tree a) (Tree a) |Empty
使用ShowTypeClass实现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?(如何使用functor实现上述函数?当然,您将实现
显示:
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
,因为它应该产生可以重构输入的输出
您可以看到如何实现树的Functor
实例
如果某个类型是Functor
类型类的实例,则意味着您可以映射它的值并保留它的上下文(使用上面的链接阅读有关Functor
的更多信息)。例如,如果在每个节点中都有tree::tree Int
和一些值,则可以使用fmap(\\\->'A')tree
将它们全部替换为'A'
字符。结果将是树字符
,但它仍然是树
要打印某些值,需要将其转换为字符串
。将tree::tree a
转换为String
将生成String
,但不再是tree Int
。这就是为什么不能使用fmap
来实现这种转换
为此,您必须遍历树a
。使用fmap
可以做的唯一一件事就是将所有值转换为String
s,然后在遍历树时以某种顺序将其连接起来。好的,这是可以重建输入的输出-在他的方案中,树a对象和它们的表示之间有一对一的映射。所以所需要的只是一个匹配的读取
的实现,对吗?@amalloy:好吧,如果任何a
生成带空格和不带分隔符的输出(例如派生显示
的默认值),那就很难了……我想在必要时可以检查它们并用括号括起来。我的意思是,对于a
,您将使用Read
实例,它解决了您的问题,对吗?我认为,您的异议同样适用于派生Show
生成的默认实例,因此这不应该是一个问题。