首页 > 解决方案 > Haskell检查函数是否两次返回相同的值

问题描述

我正在做一个项目并遇到了有趣的问题。我有一个函数,我们称之为foo这个函数将给定的数字除以可能的最高除数,而不是除以自身。如果最高分频器是 1,那么它返回给定的数字。例如,数字 21 首先除以 7 并返回 3 + 它不断返回 3,因为除了 3 和 1 之外没有其他除法器。

ghci> foo 21
3
foo it
3

现在我想将这些步骤保存到返回数组中所有步骤的函数中。当前的实现是:

bar:: int-> [int]
bar x = x : bar (foo x)

这种方法的问题是它一直返回相同的值并且永远不会结束。有没有办法检查 foo 的前一次迭代是否返回相同的数字并停止,这样它就不会导致无限列表?

就像是:

bar 21
[3]
instead of:
bar 21
[3,3,3,3,3,3,3,3,3...]

在oop中,我会将最后一个值保存到var中,然后进行比较,但是在haskell中并非如此,我不确定它还能如何实现

标签: listhaskelldivider

解决方案


你应该检查是否x等于foo x,如果是这样,我们可以停止递归,所以:

bar :: Int -> [Int]
bar x
    | x == x' = [x]
    | otherwise = x : bar x'
    where x' = foo x

你在这里也先返回给定的值。如果列表中的第一项应该是除以最大分隔符的数字,您可以使用:

bar :: Int -> [Int]
bar = go . foo
  where go x
          | x == x' = [x]
          | otherwise = x : go x'
          where x' = foo x

推荐阅读