是否可以解压缩列表的功能?

lo *_*cre 0 haskell types list

我有以下问题,我想编写一个生成嵌套列表的函数,然后将嵌套列表解压缩到一个列表中.

根据其参数生成动态程度的嵌套列表的函数显然不进行类型检查,因为返回类型将根据参数而变化.但是,是否可以递归解压缩列表以始终返回平面列表?

假设不可能的函数将为参数2返回此值:

[ [ [a], [b] ], [ [c], [d] ] ]
Run Code Online (Sandbox Code Playgroud)

这个参数为3:

[[[[a], [b], [c]], [[d], [e], [f]], [[g], [h], [i]]], [[[j], [k], [l]], [[m], [n], [o]], [[p], [q], [r]]], [[[s], [t], [u]], [[v], [w], [x]], [[y], [z], [a1]]]]
Run Code Online (Sandbox Code Playgroud)

现在我想有一些函数,我可以放入递归调用,这将导致这样的事情:

[ unpack [ unpack [a], unpack [b] ], unpack [ unpack [c], unpack [d] ] ]
Run Code Online (Sandbox Code Playgroud)

反过来会评估 [a, b, c, d]

我能够写出这样的东西只列出一个元素:

unpack [x] = x

f 1 = [0]
f n = [unpack $ f x | x <- [1..n-1]]

*Main> f 3
[0,0]
Run Code Online (Sandbox Code Playgroud)

但显然它失败了4:

*Main> f 4
[0,0,*** Exception: Non-exhaustive patterns in function unpack
Run Code Online (Sandbox Code Playgroud)

手动"跟踪":

f 3 = [unpack $ f x | x <- [1..3-1]]
    = [ unpack $ f 1, unpack $ f 2]
    = [ unpack [0], unpack [f x | x <- [1..2-1]]]
    = [ unpack [0], unpack [f 1] ]
    = [ unpack [0], unpack [0] ]
    = [0, 0]
Run Code Online (Sandbox Code Playgroud)

理论上这样的功能是否可行?我有一种强烈的感觉,不是......但也许这种感觉是错误的.

如果还没有弄清楚我的想法:这[unpack [1,2,3]]将导致列表[1,2,3].

Lon*_*ong 5

正如评论中所写,在Haskell中无法实现所需的程序.

这是一个可能的替代方法:创建数据类型

data Unpack a = Unpack [Unpack a] | Elem a
  deriving (Eq, Ord)
Run Code Online (Sandbox Code Playgroud)

此外,您可以编写一个评估解包的函数:

unpacked :: [Unpack a] -> [a]
unpacked [] = []
unpacked (Unpack x : xr) = unpacked x ++ unpacked xr
unpacked (Elem x : xr) = x : unpacked xr
Run Code Online (Sandbox Code Playgroud)

让我们让输出更漂亮:

instance Show a => Show (Unpack a) where
  show (Unpack xs) = show xs
  show (Elem x)    = show x
Run Code Online (Sandbox Code Playgroud)

ghci中的用法示例:

> list = [Unpack [Elem 1, Unpack [Elem 3, Elem 4]], Unpack [Elem 5, Elem 6, Elem 7]]
[[1,[3,4]],[5,6,7]]

> unpacked list
[1,3,4,5,6,7]
Run Code Online (Sandbox Code Playgroud)

  • FWIW,这是一个玫瑰树(仅在叶子上有值)和`toList`,你可以通过实现`Foldable`来获得它. (5认同)