作为函数输入的递归数据结构列表

时间:2017-04-14 02:12:08

标签: haskell types

我在Haskell中定义了一个递归数据结构:

data NestedList a = Element a | SubList [NestedList a]

然后我想定义一个flatten函数,它将获取NestedList列表并返回展平结果,例如:

Input: [Element 1, SubList [Element 2, SubList [] ]]
Output: [Element 1, Element 2].

但是,我对功能的定义不正确:

flatten :: NestedList a -> [a]
flatten (Element a) = [a]
flatten (SubList (x:xs)) = flatten x ++ flatten (SubList xs)
flatten (SubList []) = []

根据这个定义,我的功能将像:

flatten (SubList [Element 1, SubList []])

而不是

flatten [Element 1, SubList []]

所以这个flatten不能接受我上面提到的输入,那么我应该如何定义flatten以使它像[Element 1,SubList [Element 2,SubList []]]那样输入? / p>

2 个答案:

答案 0 :(得分:0)

如果您想将NestedList展平为平面NestedList而不是普通列表,则可以定义一个单独的函数fromList :: [a] -> NestedList a,它可以从普通列表构建一个扁平嵌套列表。

fromList :: [a] -> NestedList a
fromList l = SubList (toElems l)
  where
    toElems :: [a] -> [SubList a]
    toElems (x:xs) = Element x : toElems xs
    toElems [] = []

或只是

fromList = SubList . map Element

并写

flattenNested :: NestedList a -> NestedList a
flattenNested = fromList . flatten

当然,您也可以将flatten更简单地写为:

flatten :: NestedList a -> [a]
flatten (Element a) = [a]
flatten (SubList xs) = concat (map flatten xs)

甚至是其中一个越来越讨厌的替代品:

flatten (SubList xs) = concatMap flatten xs

由于concatMap=<<相同:

flatten (SubList xs) = flatten =<< xs

由于NestedListFree []同构,所以

flatten :: Free [] a -> [a]
flatten (Pure a) = [a]
flatten (Free xs) = flatten =<< xs

或者(ab)进一步使用这种关系:

flatten :: Free [] a -> [a]
flatten = toList

答案 1 :(得分:0)

我怀疑你正在寻找以下内容:

flatten :: [NestedList a] -> [NestedList a]
flatten (Element a  : rest) = Element a : flatten rest
flatten (SubList xs : rest) = flatten xs ++ flatten rest
flatten [] = []

似乎可以做你想做的事:

> flatten [Element 1, SubList []]
[Element 1]
> flatten [Element 1, SubList [Element 2, SubList []]]
[Element 1,Element 2]
>
相关问题