在 Haskell 中执行 while 循环

发布于 2024-10-06 00:14:04 字数 360 浏览 4 评论 0原文

我有一个函数:

isItSimple :: Int -> Bool

它获取 Int 并返回 Bool。

我需要在 [x | 中找到第一个数字x <- [n..], isItSimple x]。

这是我的解决方案:

findIt :: Int -> Int
findIt num
       | isItSimple num = num
       | otherwise = findIt (num + 1)

Haskell 有更好的解决方案吗?

I have a function:

isItSimple :: Int -> Bool

it gets Int and return Bool.

I need to find first number in [x | x <- [n..], isItSimple x].

Here is my solution:

findIt :: Int -> Int
findIt num
       | isItSimple num = num
       | otherwise = findIt (num + 1)

Is there any better solution in Haskell?

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

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

发布评论

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

评论(5

生生漫 2024-10-13 00:14:04

我需要在 [x | 中找到第一个数字x <- [n..], isItSimple x].

怎么样,就像你说的那样吧。

findIt n = head [ x | x <- [n..], isItSimple x ]

I need to find first number in [x | x <- [n..], isItSimple x].

How about just like you said.

findIt n = head [ x | x <- [n..], isItSimple x ]
彼岸花似海 2024-10-13 00:14:04

虽然其他答案有效,但它们可以说不是在 Haskell 中解决这个问题的最惯用的方法。您实际上并不需要任何额外的导入:Prelude 中的几个函数就可以解决问题。

我首先创建一个包含所有大于或等于 n 的简单数字的列表。函数 filter :: (a -> Bool) -> [一]-> [a] 使这变得简单:

filter isItSimple [n..]

就像 [n..] 这是一个无限列表,但这不是问题,因为 Haskell 很懒,在需要时不会评估任何内容。

为了得到你想要的,你可以只获取这个无限列表的头部:

findIt :: Int -> Int
findIt n = head $ filter isItSimple [n..]

有些人不喜欢 head 因为它是一个部分函数,​​并且当给它一个空列表时会引发异常。我个人不会在这里担心这一点,因为我们知道它永远不会在空列表上被调用。与 fromJust 相比,它让我不那么不舒服,它也是一个部分函数(当给出 Nothing 时它会引发异常),在我看来这始终是一个坏主意。

(说到个人品味,我会这样写:

findIt = head . filter isItSimple . enumFrom

这是一个 pointfree 风格的示例,可以得到在我看来,这很复杂,但在这种情况下非常优雅。)

While the other answers work, they're arguably not the most idiomatic way to solve this problem in Haskell. You don't really need any extra imports: a couple of functions from the Prelude will do the trick.

I'd start by creating a list of all of the simple numbers greater than or equal to n. The function filter :: (a -> Bool) -> [a] -> [a] makes this easy:

filter isItSimple [n..]

Like [n..] this is an infinite list, but this isn't a problem since Haskell is lazy and won't evaluate anything until it's needed.

To get what you want you can just take the head of this infinite list:

findIt :: Int -> Int
findIt n = head $ filter isItSimple [n..]

Some people don't like head since it's a partial function and will raise an exception when it's given an empty list. I personally wouldn't worry about that here, since we know it will never be called on an empty list. It makes me much less uncomfortable than fromJust, which is also a partial function (it raises an exception when given Nothing) and in my opinion is always a bad idea.

(And speaking of personal taste, I'd write this as follows:

findIt = head . filter isItSimple . enumFrom

This is an example of pointfree style, which can get convoluted but in this case is very elegant, in my opinion.)

你怎么这么可爱啊 2024-10-13 00:14:04

在大多数情况下,特别是当您的问题是已解决问题的特定情况时,显式递归是不好的。不使用显式递归的问题的可能解决方案之一是:

import Data.List (find)
import Data.Maybe (fromJust)

findIt :: Int -> Int
findIt n = fromJust $ find isItSimple [n..]

In most cases, especially when your problem is a particular case of solved one, explicit resursion is bad. One of possible solutions of your problem without using explicit recursion is:

import Data.List (find)
import Data.Maybe (fromJust)

findIt :: Int -> Int
findIt n = fromJust $ find isItSimple [n..]
寄风 2024-10-13 00:14:04
findIt :: Int -> Int
findIt num = head $ dropWhile (not isItSimple) [num..]

我不知道是否会更好。我刚刚想到了这一点。

findIt :: Int -> Int
findIt num = head $ dropWhile (not isItSimple) [num..]

I don't know if it's better. It just came to my mind.

花开柳相依 2024-10-13 00:14:04

另一种方法是使用最小定点组合器(在 Data.Function 中修复)

findIt = fix (\f x ->  if isItSimple x then x else f (x + 1))

在这种情况下,它看起来有点过度设计,但如果“搜索空间”遵循比 x + 1 更复杂的规则code> 这种技术非常有用。

Another way is to use the least fixed point combinator (fix in Data.Function)

findIt = fix (\f x ->  if isItSimple x then x else f (x + 1))

In this case it looks a little bit over-engineered, but if the "search space" follows a more complicated rule than x + 1 this technique can be quite useful.

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