【问题标题】:How do I find an element in an infinite list using the foldr function in Haskell?如何使用 Haskell 中的 foldr 函数在无限列表中查找元素?
【发布时间】:2015-12-24 22:20:32
【问题描述】:

我正在尝试使用 foldr 函数在 Haskell 中创建 elem 函数的新实现。

到目前为止,我有这个:

count :: Eq a => a -> [a] -> Integer
count x (y:ys) = foldl (\counter y -> if y == x then counter + 1 else counter) 0 ys
count _ [] = 0

elem' :: Eq a => a -> [a] -> Bool
elem' x (y:ys) = foldr (\i elem-> if (count x (y:ys)) > 0 then True else False) False ys
elem' _ [] = False

count 函数使用foldl 计算 x(我写的另一个函数)的出现次数。这适用于有限列表,但问题是我想利用无限列表的 foldr 惰性计算。如果我尝试使用无限列表作为输入,程序将永远挂起。

基本上,一旦我在列表中找到任何 x 实例并返回 true,我想“突破”,否则返回 false。

感谢您的帮助。

【问题讨论】:

  • 是的,尝试使用foldr 而不是foldl。尽管计算一个无限的列表总是会挂起。我不知道你为什么要在你的elem 实现中使用count
  • 你在那个 lambda 中既没有使用i 也没有使用elem。那么,你折叠到底是为了什么?另外,如果你使用折叠,你不应该使用结构递归(带有模式匹配)
  • 试试elem' x = foldr (\el elemInRest -> el == x || elemInRest) false
  • @Bergi,它可能会在依赖类型设置中节省一些证明,使用归纳列表和惰性自然,但计算无限列表的元素意义不大。
  • @dfeuer:我知道有人会抓住“总是” :-) 是的,用懒惰的 Peano 数字它可能是适用的,无论如何在证明中是肯定的,但它没有意义OP。

标签: haskell functional-programming find element fold


【解决方案1】:

让我们从foldr 模式的基本骨架开始:

elem :: Eq a => [a] -> Bool
elem x xs = foldr kons knil xs

foldr 看到[] 时,它会返回knil。由于空列表中没有任何元素,因此我们得出结论

knil = False

foldr kons False 看到列表a : as 时,它会返回kons a (foldr kons False as)。我们可以归纳地假设foldr kons False as = elem x as,因此我们寻求解决kons in

elem x (a : as) = kons a (elem x as)

我敢打赌,你可以通过提出kons 的定义来完成。注意布尔短路行为,以提高效率并避免无限列表的问题。

【讨论】:

    猜你喜欢
    • 2015-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    • 2017-04-16
    相关资源
    最近更新 更多