在 Haskell 中反转自定义嵌套列表
Reverse a custom nested list in Haskell
我正在尝试反转 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]
您的嵌套列表实际上是一棵树,其元素位于 leafess:
SubList
/ \
SubList Elem 4
/ | \
Elem 1 Elem 2 Elem 3
因此您的 myreverse
将是水平翻转,即 SubList
中每个列表的递归 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 的标准列表,反向已经定义。
我的问题是:如果链表头也是链表怎么处理?我知道需要发生的是我反转列表的头部并将其放回尾部的反面。但是如何实现呢?
为什么不这样
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]
您的嵌套列表实际上是一棵树,其元素位于 leafess:
SubList
/ \
SubList Elem 4
/ | \
Elem 1 Elem 2 Elem 3
因此您的 myreverse
将是水平翻转,即 SubList
中每个列表的递归 reverse
,正如其他答案所指出的那样。
这里的教训:可视化数据结构有助于理解和实施对它们的操作。