【问题标题】:Code doesnt work with infinite lists代码不适用于无限列表
【发布时间】:2015-06-12 00:04:38
【问题描述】:

我目前正在研究一个函数,它接受 2 个整数和一个列表作为参数,并返回一个列表,其中第一个列表的元素位于这 2 个整数之间的位置(函数 :: Int->Int->[ u]->[u])。例如:

>function 2 5 [1..10]

返回

[2,3,4,5]

上面的示例正在使用我当前的代码......但是如果我插入一个像 [0..] 这样的无限列表,它会返回一个“错误 - 垃圾收集无法回收足够的空间”。有什么建议? 这是代码

function :: Int->Int->[u]->[u]                                                       
function i j s
    |i<0 = function 0 j s
    |j< length s = function i j (init s) 
    |j-i< (length s)-1 = function i j (tail s)
    |otherwise = s

【问题讨论】:

  • 如果你不发布源代码,我们怎么知道你的实现哪里出错了?
  • 你说得对,已编辑。我没有发布代码,因为我没有写一些东西来处理无限列表......
  • function 有点奇怪;我们通常在 Haskell 中索引从 0 开始的列表,而不是从 1 开始。也就是说,您可以根据前奏函数droptake 轻松定义它,它们都可以在无限列表上正确运行。 function start end = drop (start - 1) . take end.
  • @Cirdec 差不多,但在这种情况下,如果我没记错的话,示例将是 [2,3,4,5,6]

标签: haskell


【解决方案1】:

您的实现的问题是使用了length。将length 与无限列表一起用作参数不是一个好主意,因为列表无限长。

我建议更改实现以使用可以在无限列表上工作的其他函数,例如 droptake

function :: Int -> Int -> [a] -> [a]
function i j list = take (i - j + 1) (drop (i - 1) list)

或者,无点:

function i j = take (j - i + 1) . drop (i - 1)

【讨论】:

  • Int-&gt;Int-&gt;[u]-&gt;[u] 类型的函数不能在列表中“搜索”其参数,因为无法将 uInt 进行比较。整数参数被描述为列表中的“位置”或索引。
  • 感谢您的回答,代码有效,但无法处理否定输入。我添加了这个,现在可以了:|i&lt;0 = function 0 j list |otherwise = take (j - i + 1) (drop (i - 1) list)
【解决方案2】:

怎么样:无限列表的长度? 我认为这是不可能的。

【讨论】:

  • 当然,无限列表没有长度。我已经知道我的代码不适用于无限列表。我只是想知道一种将无限列表作为输入处理并返回正确结果的方法。
【解决方案3】:

一种基于压缩索引并过滤掉不在给定范围内的方法,

f :: Int -> Int -> [a] -> [a]
f i j = map (snd) . filter (\v -> fst v `elem` [i..j]) . zip [1..]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-17
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-28
    • 1970-01-01
    相关资源
    最近更新 更多