【问题标题】:Haskell check if function returned same value twiceHaskell检查函数是否两次返回相同的值
【发布时间】:2021-10-01 10:21:21
【问题描述】:

我正在做一个项目并遇到了有趣的问题。我有一个函数,我们称之为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 中并非如此,我不确定它还能如何实现

【问题讨论】:

  • 这里另一个好的通用方法是基于经典的斐波那契示例fibs = 1 : 1 : zipWith (+) fibs (drop 1 fibs)。给定一个列表xs,如[1, 2, 3, 3, 3],成语zip xs (drop 1 xs)(或zip xs (tail xs))将每个元素与其邻居配对,如[(1, 2), (2, 3), (3, 3), (3, 3)]。您可以使用span/breaktakeWhile/dropWhile 等函数来选择所需的前缀。这些操作也可以很自然地组合成一个折叠。

标签: list haskell divider


【解决方案1】:

你应该检查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

【讨论】:

    【解决方案2】:

    如果首选库样式,还可以使用unfoldr 库函数。

    通用代码如下:

     λ> 
     λ> :type unfoldr
     unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
     λ> 
     λ> stepFn f v = if (v == f v) then Nothing else Just (let fv = f v in (fv, fv))
     λ> bar f v0 = v0 : L.unfoldr (stepFn f) v0
     λ> 
    

    作为一只豚鼠,我们可以选择一个迭代求整数平方根的函数,例如 709。请注意,如果没有一些额外的调整,它并不适用于所有数字,这只会模糊我们的目的。

     λ> 
     λ> foo n = div (n + div 709 n) 2
     λ> 
     λ> foo 1
     355
     λ> 
     λ> foo 355
     178
     λ> 
     λ> foo 26
     26
     λ> 
    

    那么让我们试试bar:

     λ> 
     λ> :type bar
     bar :: Eq b => (b -> b) -> b -> [b]
     λ> 
     λ> bar foo 1
     [1,355,178,90,48,31,26]
     λ> 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-10
      • 1970-01-01
      • 2012-01-10
      • 1970-01-01
      • 1970-01-01
      • 2012-07-02
      • 2014-02-03
      相关资源
      最近更新 更多