在 Haskell 中执行 while 循环
我有一个函数:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
怎么样,就像你说的那样吧。
How about just like you said.
虽然其他答案有效,但它们可以说不是在 Haskell 中解决这个问题的最惯用的方法。您实际上并不需要任何额外的导入:Prelude 中的几个函数就可以解决问题。
我首先创建一个包含所有大于或等于 n 的简单数字的列表。函数
filter :: (a -> Bool) -> [一]-> [a]
使这变得简单:就像
[n..]
这是一个无限列表,但这不是问题,因为 Haskell 很懒,在需要时不会评估任何内容。为了得到你想要的,你可以只获取这个无限列表的头部:
有些人不喜欢
head
因为它是一个部分函数,并且当给它一个空列表时会引发异常。我个人不会在这里担心这一点,因为我们知道它永远不会在空列表上被调用。与fromJust
相比,它让我不那么不舒服,它也是一个部分函数(当给出Nothing
时它会引发异常),在我看来这始终是一个坏主意。(说到个人品味,我会这样写:
这是一个 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 functionfilter :: (a -> Bool) -> [a] -> [a]
makes this easy: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:
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 thanfromJust
, which is also a partial function (it raises an exception when givenNothing
) and in my opinion is always a bad idea.(And speaking of personal taste, I'd write this as follows:
This is an example of pointfree style, which can get convoluted but in this case is very elegant, in my opinion.)
在大多数情况下,特别是当您的问题是已解决问题的特定情况时,显式递归是不好的。不使用显式递归的问题的可能解决方案之一是:
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:
我不知道是否会更好。我刚刚想到了这一点。
I don't know if it's better. It just came to my mind.
另一种方法是使用最小定点组合器(在 Data.Function 中修复)
在这种情况下,它看起来有点过度设计,但如果“搜索空间”遵循比 x + 1 更复杂的规则code> 这种技术非常有用。
Another way is to use the least fixed point combinator (fix in Data.Function)
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.