在Haskell

时间:2016-04-08 21:03:05

标签: 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 :: NestedList a -> NestedList a

我认为这是有道理的,因为我只是重新排列列表中的元素。

我理解如何编写基本的反向函数,而且我也知道对于Haskell的标准列表,反向已经定义了。

我的问题是:如何处理列表头部也是列表的情况?我知道需要发生的是我将列表的头部反转并将其放回尾部的反面。但是如何实现这个目标呢?

2 个答案:

答案 0 :(得分:4)

为什么不这样呢

rev :: NestedList a -> NestedList a
rev (Elem a) = Elem a
rev (SubList xs) = SubList $ map rev $ reverse xs

如果将derinding(Show)添加到数据定义中,

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]

答案 1 :(得分:3)

您的嵌套列表实际上是一个树,其中的元素位于leavess:

                 SubList
               /         \
        SubList           Elem 4
    /      |      \
Elem 1   Elem 2   Elem 3

因此,您的myreverse将是reverse中的每个列表的水平翻转,即递归SubList,与其他答案一样。

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