删除Haskell中出现的所有Nil

删除Haskell中出现的所有Nil,haskell,tree,comparison,Haskell,Tree,Comparison,在大学里,我们接到了写函数的任务 >deleteNil::树a->树a 即删除该类型树中出现的所有Nil >数据树a=Nil |叶a | Br(树a)(树a) 如果树只包含Nil,则返回值也应为Nil。 唯一的限制是树的类型签名和函数deleteNil的签名都不允许编辑,例如,我不允许追加 导出等式,显示 到树a的类型签名 我第一次尝试解决这个问题如下: > deleteNil :: Tree a -> Tree a > deleteNil Nil = Nil > del

在大学里,我们接到了写函数的任务

>deleteNil::树a->树a

即删除该类型树中出现的所有Nil

>数据树a=Nil |叶a | Br(树a)(树a)

如果树只包含Nil,则返回值也应为Nil。 唯一的限制是树的类型签名和函数deleteNil的签名都不允许编辑,例如,我不允许追加
导出等式,显示
到树a的类型签名

我第一次尝试解决这个问题如下:

> deleteNil :: Tree a -> Tree a
> deleteNil Nil = Nil
> deleteNil (Br l r)
>        | deleteNil l == Nil && deleteNil r == Nil = Nil
>        | deleteNil l == Nil && deleteNil r /= Nil = r
>        | deleteNil l /= Nil && deleteNil r == Nil = l
>        | deleteNil l /= Nil && deleteNil r /= Nil = Br l r
但是很明显,因为我不被允许导出Eq,这个版本给了我编译错误

没有因使用“==”而产生的(Eq(树a))实例。


我不想在这里要求这个问题的完整解决方案,但有人能为我提供一种新的方法吗?我应该如何尝试解决这个问题而不必比较树的各个部分?

好吧,你几乎做到了,你缺少的是你也可以在
l
r
上进行模式匹配:

deleteNil :: Tree a -> Tree a
deleteNil Nil = Nil
deleteNil (Br Nil Nil) = Nil
deleteNil (Br   l Nil) = (deleteNil l)
deleteNil (Br Nil   r) = (deleteNil r)
deleteNil (Br   l   r) = case (deleteNil l, deleteNil r) of
    (Nil, Nil) -> Nil
    (nl, Nil) -> nl
    (Nil, nr) -> nr
    (nl, nr) -> Br nl nr

在函数中也要仔细考虑<代码>叶<代码>选项。

你几乎是正确的,你缺少的是你可以在 L/<代码>和<代码> r>代码>下匹配:

deleteNil :: Tree a -> Tree a
deleteNil Nil = Nil
deleteNil (Br Nil Nil) = Nil
deleteNil (Br   l Nil) = (deleteNil l)
deleteNil (Br Nil   r) = (deleteNil r)
deleteNil (Br   l   r) = case (deleteNil l, deleteNil r) of
    (Nil, Nil) -> Nil
    (nl, Nil) -> nl
    (Nil, nr) -> nr
    (nl, nr) -> Br nl nr

在函数中也要仔细考虑<代码>叶<代码>选项。

你几乎是正确的,你缺少的是你可以在 L/<代码>和<代码> r>代码>下匹配:

deleteNil :: Tree a -> Tree a
deleteNil Nil = Nil
deleteNil (Br Nil Nil) = Nil
deleteNil (Br   l Nil) = (deleteNil l)
deleteNil (Br Nil   r) = (deleteNil r)
deleteNil (Br   l   r) = case (deleteNil l, deleteNil r) of
    (Nil, Nil) -> Nil
    (nl, Nil) -> nl
    (Nil, nr) -> nr
    (nl, nr) -> Br nl nr

在函数中也要仔细考虑<代码>叶<代码>选项。

你几乎是正确的,你缺少的是你可以在 L/<代码>和<代码> r>代码>下匹配:

deleteNil :: Tree a -> Tree a
deleteNil Nil = Nil
deleteNil (Br Nil Nil) = Nil
deleteNil (Br   l Nil) = (deleteNil l)
deleteNil (Br Nil   r) = (deleteNil r)
deleteNil (Br   l   r) = case (deleteNil l, deleteNil r) of
    (Nil, Nil) -> Nil
    (nl, Nil) -> nl
    (Nil, nr) -> nr
    (nl, nr) -> Br nl nr

<>请仔细考虑函数中的<代码>叶<代码>选项。

可以使用模式匹配:

deleteNil :: Tree a -> Tree a
deleteNil (Br l r) = case (deleteNil l, deleteNil r) of
    (Nil, dr ) -> dr
    (dl , Nil) -> dl
    (dl , dr ) -> Br dl dr
deleteNil  t       = t
所以你不需要四个箱子,因为这两个

| deleteNil l == Nil && deleteNil r == Nil = Nil
| deleteNil l == Nil && deleteNil r /= Nil = r
实际上是这样的:

| deleteNil l == Nil = deleteNil r
因为它应该是

| deleteNil l == Nil && deleteNil r /= Nil = deleteNil r
因为您想要返回一个树,所以它不包含
Nil
s

此外,您还可以为
Eq
typeclass提供一个实例:

instance Eq (Tree a) where
    Nil      == Nil      = True
    Br l1 r1 == Br l2 r2 = l1 == l2 && r1 == r2
    _        == _        = False

您可以使用模式匹配:

deleteNil :: Tree a -> Tree a
deleteNil (Br l r) = case (deleteNil l, deleteNil r) of
    (Nil, dr ) -> dr
    (dl , Nil) -> dl
    (dl , dr ) -> Br dl dr
deleteNil  t       = t
所以你不需要四个箱子,因为这两个

| deleteNil l == Nil && deleteNil r == Nil = Nil
| deleteNil l == Nil && deleteNil r /= Nil = r
实际上是这样的:

| deleteNil l == Nil = deleteNil r
因为它应该是

| deleteNil l == Nil && deleteNil r /= Nil = deleteNil r
因为您想要返回一个树,所以它不包含
Nil
s

此外,您还可以为
Eq
typeclass提供一个实例:

instance Eq (Tree a) where
    Nil      == Nil      = True
    Br l1 r1 == Br l2 r2 = l1 == l2 && r1 == r2
    _        == _        = False

您可以使用模式匹配:

deleteNil :: Tree a -> Tree a
deleteNil (Br l r) = case (deleteNil l, deleteNil r) of
    (Nil, dr ) -> dr
    (dl , Nil) -> dl
    (dl , dr ) -> Br dl dr
deleteNil  t       = t
所以你不需要四个箱子,因为这两个

| deleteNil l == Nil && deleteNil r == Nil = Nil
| deleteNil l == Nil && deleteNil r /= Nil = r
实际上是这样的:

| deleteNil l == Nil = deleteNil r
因为它应该是

| deleteNil l == Nil && deleteNil r /= Nil = deleteNil r
因为您想要返回一个树,所以它不包含
Nil
s

此外,您还可以为
Eq
typeclass提供一个实例:

instance Eq (Tree a) where
    Nil      == Nil      = True
    Br l1 r1 == Br l2 r2 = l1 == l2 && r1 == r2
    _        == _        = False

您可以使用模式匹配:

deleteNil :: Tree a -> Tree a
deleteNil (Br l r) = case (deleteNil l, deleteNil r) of
    (Nil, dr ) -> dr
    (dl , Nil) -> dl
    (dl , dr ) -> Br dl dr
deleteNil  t       = t
所以你不需要四个箱子,因为这两个

| deleteNil l == Nil && deleteNil r == Nil = Nil
| deleteNil l == Nil && deleteNil r /= Nil = r
实际上是这样的:

| deleteNil l == Nil = deleteNil r
因为它应该是

| deleteNil l == Nil && deleteNil r /= Nil = deleteNil r
因为您想要返回一个树,所以它不包含
Nil
s

此外,您还可以为
Eq
typeclass提供一个实例:

instance Eq (Tree a) where
    Nil      == Nil      = True
    Br l1 r1 == Br l2 r2 = l1 == l2 && r1 == r2
    _        == _        = False


非常感谢,我现在将尝试此线索,并在大约一个小时或更短的时间内发布更新:)哇,您的模板非常棒:我所要做的就是附加
>delNil(Leaf a)=Leaf a
,以使此工作如期进行,谢谢!不幸的是,我没有15%的声誉来支持这个伟大的答案,但你应该确信,一旦我找到了他们,我会而且会的。@JoeCocker很高兴我能帮上忙。你应该接受和/或更新答案,以向其他人展示它的有用性,除非你觉得你可以制定一个更好的答案,在这种情况下,你应该发布它。没错,我忘了我也可以接受答案,不仅仅是更新答案,我的坏:)现在赶上了:)这似乎应该在最后一个案例中生成一个无限循环?非常感谢,我现在将尝试这个线索,并在大约一个小时或更短的时间内发布更新:)哇,你的模板非常棒:我所要做的就是附加
>delNil(Leaf a)=Leaf a
,以使这一切按预期工作,谢谢!不幸的是,我没有15%的声誉来支持这个伟大的答案,但你应该确信,一旦我找到了他们,我会而且会的。@JoeCocker很高兴我能帮上忙。你应该接受和/或更新答案,以向其他人展示它的有用性,除非你觉得你可以制定一个更好的答案,在这种情况下,你应该发布它。没错,我忘了我也可以接受答案,不仅仅是更新答案,我的坏:)现在赶上了:)这似乎应该在最后一个案例中生成一个无限循环?非常感谢,我现在将尝试这个线索,并在大约一个小时或更短的时间内发布更新:)哇,你的模板非常棒:我所要做的就是附加
>delNil(Leaf a)=Leaf a
,以使这一切按预期工作,谢谢!不幸的是,我没有15%的声誉来支持这个伟大的答案,但你应该确信,一旦我找到了他们,我会而且会的。@JoeCocker很高兴我能帮上忙。你应该接受和/或更新答案,以向其他人展示它的有用性,除非你觉得你可以制定一个更好的答案,在这种情况下,你应该发布它。没错,我忘了我也可以接受答案,不仅仅是更新答案,我的坏:)现在赶上了:)这似乎应该在最后一个案例中生成一个无限循环?非常感谢,我现在将尝试这个线索,并在大约一个小时或更短的时间内发布更新:)哇,你的模板非常棒:我所要做的就是附加
>delNil(Leaf a)=Leaf a
,以使这一切按预期工作,谢谢!不幸的是,我没有15%的声誉来支持这个伟大的答案,但你应该确信,一旦我找到了他们,我会而且会的。@JoeCocker很高兴我能帮上忙。你应该接受和/或投票表决答案,以向其他人展示它的有用性,除非你觉得你可以制定一个更好的答案,在这种情况下,你应该发布它。对了,我忘了我也可以