你将如何在 Haskell 中(重新)实现迭代?

发布于 2024-09-24 15:13:22 字数 439 浏览 10 评论 0原文

iterate :: (a -> a) -> a -> [a]

(您可能知道)iterate 是一个接受函数和起始值的函数。然后它将函数应用于起始值,然后将相同的函数应用于最后的结果,依此类推。

Prelude> take 5 $ iterate (^2) 2
[2,4,16,256,65536]
Prelude> 

结果是一个无限列表。 (这就是我使用 take 的原因)。 我的问题是,您如何在 Haskell 中实现自己的 iterate' 函数,仅使用基础知识 ((:) (++) lambdas、pattern匹配、守卫等)?

(哈斯克尔初学者在这里)

iterate :: (a -> a) -> a -> [a]

(As you probably know) iterate is a function that takes a function and starting value. Then it applies the function to the starting value, then it applies the same function to the last result, and so on.

Prelude> take 5 $ iterate (^2) 2
[2,4,16,256,65536]
Prelude> 

The result is an infinite list. (that's why I use take).
My question how would you implement your own iterate' function in Haskell, using only the basics ((:) (++) lambdas, pattern mataching, guards, etc.) ?

(Haskell beginner here)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

鹿! 2024-10-01 15:13:22

嗯,iterate 构造了一个由 a 递增的无限值列表 f。因此,我首先编写一个函数,将一些值 a 添加到通过使用 f a 递归调用 iterate 构建的列表中:

iterate :: (a -> a) -> a -> [a]
iterate f a = a : iterate f (f a)

由于惰性求值,仅构建列表的该部分将评估计算我的函数值所必需的。

Well, iterate constructs an infinite list of values a incremented by f. So I would start by writing a function that prepended some value a to the list constructed by recursively calling iterate with f a:

iterate :: (a -> a) -> a -> [a]
iterate f a = a : iterate f (f a)

Thanks to lazy evaluation, only that portion of the constructed list necessary to compute the value of my function will be evaluated.

盛夏已如深秋| 2024-10-01 15:13:22

另请注意,您可以在报告的 Standard Prelude< 中找到基本 Haskell 函数范围的简明定义/a>.

阅读这个简单的定义列表,这些定义本质上是从原始基元中引导出一个丰富的库,在提供“haskell 方式”的窗口方面非常有教育意义,并且令人大开眼界。

我记得很早的时候读到的一个顿悟时刻:data Bool = False |确实如此。

Also note that you can find concise definitions for the range of basic Haskell functions in the report's Standard Prelude.

Reading through this list of straightforward definitions that essentially bootstrap a rich library out of raw primitives can be very educational and eye-opening in terms of providing a window onto the "haskell way".

I remember a very early aha moment on reading: data Bool = False | True.

人海汹涌 2024-10-01 15:13:22

您已经获得了它的最简单的实现;然而,还有其他方法。

一种方法是使用高阶函数,如下所示:

import Data.List (unfoldr)

iterate f x = unfoldr (\x -> Just (x, f x)) x

函数 unfoldr 是一个用于创建列表的高阶函数。这是它最直接的实现:

unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
unfoldr step b = case step b of 
  Nothing -> []
  Just (a, b') -> a : unfoldr step b'

foldr 抽象减少列表的直接递归的方式相同,unfoldr 抽象创建它们的直接递归。

You've already been given the simplest possible implementation of it; however, there are other ways.

One way is to use a higher order function, like so:

import Data.List (unfoldr)

iterate f x = unfoldr (\x -> Just (x, f x)) x

The function unfoldr is a higher-order function meant for creating lists. Here's the most straightforward implementation of it:

unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
unfoldr step b = case step b of 
  Nothing -> []
  Just (a, b') -> a : unfoldr step b'

In the same way that foldr abstracts of the direct recursion of reducing lists, unfoldr abstracts over the direct recursion of creating them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文