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

Haskell 作为函数输入的递归数据结构列表,haskell,types,Haskell,Types,我在Haskell中定义了一个递归数据结构: data NestedList a = Element a | SubList [NestedList a] 然后我想定义一个展平函数,它将获取NestedList列表并返回展平结果,例如: Input: [Element 1, SubList [Element 2, SubList [] ]] Output: [Element 1, Element 2]. 但是,我对函数的定义不正确: flatten :: NestedList a ->

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

data NestedList a = Element a | SubList [NestedList a]
然后我想定义一个
展平
函数,它将获取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 []]

因此,这个
展平
不能接受我上面提到的输入,那么我应该如何定义
展平
以使它像[Element 1,SubList[Element 2,SubList[]]那样接受输入?

如果您想将
嵌套列表
展平成一个平面
嵌套列表
,您可以定义一个单独的函数
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
当然,您也可以更简单地将
flant
本身编写为:

flatten :: NestedList a -> [a]
flatten (Element a) = [a]
flatten (SubList xs) = concat (map flatten xs)
甚至是这些越来越书呆子的替代品之一:

flatten (SubList xs) = concatMap flatten xs

由于
concatMap
=相同,我怀疑您正在寻找以下内容:

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]
>

在什么方面这不是你想要的定义?在我看来,它工作得很好-结果将是
[1]
,如果您想将该结果的每个元素包装在
元素中(无论出于何种原因…),那么只需执行
映射元素即可。展平
。一个更简单、等效的定义是将最后两个子句替换为展平(子列表xs)=xs>>=展平
。FWIW,
嵌套列表
只是
自由【】
,展平
只是
实例可折叠f=>可折叠(自由f)
实例可折叠【】
。如果这不是您想要的,您想要什么?我的意思是我需要像[Element 1,SubList[]]这样的输入,而不是子列表[Element 1,SubList[]]。
flatten :: Free [] a -> [a]
flatten = toList
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]
>