Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 哈斯克尔:如何使用;“衍生秀”;函子呢?_Haskell - Fatal编程技术网

Haskell 哈斯克尔:如何使用;“衍生秀”;函子呢?

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

问题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 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
生成的默认实例,因此这不应该是一个问题。