List 在Haskell中反转自定义嵌套列表

List 在Haskell中反转自定义嵌套列表,list,haskell,nested,reverse,List,Haskell,Nested,Reverse,我正在努力反转Haskell中的嵌套列表。我知道嵌套列表在Haskell中不存在,所以我定义了一个: data NestedList a = Elem a | SubList [NestedList a] 我还有一个展平功能: flatten :: NestedList a -> [a] flatten (Elem x) = [x] flatten (SubList x) = concatMap flatten x 现在我想写我的反向函数。该功能定义为: myreverse :: Ne

我正在努力反转Haskell中的嵌套列表。我知道嵌套列表在Haskell中不存在,所以我定义了一个:

data NestedList a = Elem a | SubList [NestedList a]
我还有一个展平功能:

flatten :: NestedList a -> [a]
flatten (Elem x) = [x]
flatten (SubList x) = concatMap flatten x
现在我想写我的反向函数。该功能定义为:

myreverse :: NestedList a -> NestedList a
我认为这很有意义,因为我只是在重新排列列表中的元素

我了解如何编写一个基本的反向函数,我还知道Haskell的标准列表已经定义了反向函数

我的问题是:我如何处理列表的头也是一个列表的情况?我知道需要做的是,我把列表的开头颠倒过来,然后把它放回尾部的反面。但是如何做到这一点呢?

为什么不这样做呢

rev :: NestedList a -> NestedList a
rev (Elem a) = Elem a
rev (SubList xs) = SubList $ map rev $ reverse xs
如果将派生显示添加到数据定义中

Prelude> rev $ SubList [Elem 1, SubList [Elem 2, Elem 3]]
SubList [SubList [Elem 3,Elem 2],Elem 1]

Prelude> rev $ SubList [Elem 1, SubList []]
SubList [SubList [],Elem 1]
为什么不这样呢

rev :: NestedList a -> NestedList a
rev (Elem a) = Elem a
rev (SubList xs) = SubList $ map rev $ reverse xs
如果将派生显示添加到数据定义中

Prelude> rev $ SubList [Elem 1, SubList [Elem 2, Elem 3]]
SubList [SubList [Elem 3,Elem 2],Elem 1]

Prelude> rev $ SubList [Elem 1, SubList []]
SubList [SubList [],Elem 1]

嵌套列表实际上是一棵树,其中的元素位于左侧:

                 SubList
               /         \
        SubList           Elem 4
    /      |      \
Elem 1   Elem 2   Elem 3
所以您的myreverse将是一个水平翻转,即子列表中每个列表的递归反转,正如其他答案所指出的


这里的教训是:可视化数据结构有助于理解和实施对它们的操作。

您的嵌套列表实际上是一棵树,其左边有元素:

                 SubList
               /         \
        SubList           Elem 4
    /      |      \
Elem 1   Elem 2   Elem 3
所以您的myreverse将是一个水平翻转,即子列表中每个列表的递归反转,正如其他答案所指出的

这里的教训是:可视化数据结构有助于理解和实施对它们的操作