【问题标题】:Is a function that unpacks lists possible?可以解包列表的功能吗?
【发布时间】:2018-02-01 05:20:48
【问题描述】:

我有以下问题,我想写一个生成嵌套列表的函数,然后将嵌套列表解包成一个列表。

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

假设不可能的函数会为参数 2 返回 this:

[ [ [a], [b] ], [ [c], [d] ] ]

这对于 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]]]]

现在我想要一些可以放入递归调用中的函数,这将导致如下结果:

[ unpack [ unpack [a], unpack [b] ], unpack [ unpack [c], unpack [d] ] ]

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

我可以为只有一个元素的列表写这样的东西:

unpack [x] = x

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

*Main> f 3
[0,0]

但显然它失败了 4:

*Main> f 4
[0,0,*** Exception: Non-exhaustive patterns in function unpack

手动“跟踪”:

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]

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

如果还不清楚我的想法:这个[unpack [1,2,3]] 将导致列表[1,2,3]

【问题讨论】:

  • length [unpack [1,2,3]] == 1,但是length [1,2,3] == 3,所以把这两者等同起来是矛盾的
  • 如果unpacklength 之前被评估,不是吗?
  • 长度独立于列表元素的评估(只要不会使程序崩溃)。不管你如何实施解包
  • 因此,由于矛盾,即使在语义上也是不可能的。但是...我的意思是...我可以手动执行此功能...为什么?这里的中心错误是什么?
  • 你认为unpack [1,2,3] 本身应该评估什么?

标签: list haskell types


【解决方案1】:

如 cmets 中所写,您想要的程序在 Haskell 中是不可能的。

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

data Unpack a = Unpack [Unpack a] | Elem a
  deriving (Eq, Ord)

您还可以编写一个评估拆包的函数:

unpacked :: [Unpack a] -> [a]
unpacked [] = []
unpacked (Unpack x : xr) = unpacked x ++ unpacked xr
unpacked (Elem x : xr) = x : unpacked xr

让输出更漂亮:

instance Show a => Show (Unpack a) where
  show (Unpack xs) = show xs
  show (Elem x)    = show x

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]

【讨论】:

猜你喜欢
  • 2021-05-27
  • 2014-01-26
  • 2019-08-24
  • 1970-01-01
  • 2014-09-04
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
  • 2020-04-20
相关资源
最近更新 更多