我在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>
答案 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
由于NestedList
与Free []
同构,所以
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]
>