计算递归次数

Gai*_*ius 4 haskell

我有一些代码可以反复接近一个解决方案,它实际上做的并不重要,但它通过改变mg(m猜测,从4.0开始因为我"知道"它应该在球场中)而对r'== rt有效. .

solve_m f ar st qt = solve_m' f ar st qt 4.0
  where
    solve_m' f ar st qt mg 
      | rd > precis    = f' (mg - sf)  
      | rd < (-precis) = f' (mg + sf)  
      | otherwise = mg
        where 
          f' = solve_m' f ar st qt
          rt = st + qt   
          r' = f st ar mg 
          rd = rt - r'    
          sf = abs(rd) 
Run Code Online (Sandbox Code Playgroud)

我想要做的是计算周期数,我知道正确的方法是使用State monad,但是最优雅的方法是将put/get放入这样的函数中?让f'成为阻止?或者只是添加一个计数器solve_m'并返回(counter,mg)?

谢谢!

编辑:这似乎基本上是我想要的,没有必要的Monads:

solve_m f ar st qt = (last (series), length(series))
  where
  series = takeWhile termPred (iterate solve_m' 4.0)
  termPred m' = (abs (rt - (f st ar m'))) > precis
  rt = st + qt   
  solve_m' mg 
    | rt > r' = (mg - sf)  
    | rt < r' = (mg + sf)  
      where
        r' = f st ar mg 
        rd = rt - r' 
        sf = abs(rd)
Run Code Online (Sandbox Code Playgroud)

仍然看起来有点凌乱(重复的代码),但我会整理它...这将在我将取代的代码的迭代的1/10000中获得可接受的结果!

Tho*_*son 5

在不查看算法的情况下,执行此操作的一般方法是从迭代算法中划分终止条件:

terminationPred :: a -> Bool
algorithm :: a -> a
Run Code Online (Sandbox Code Playgroud)

然后使用iterate和takeWhile:

itermediates = takeWhile (not . terminationPred) . iterate algorithm
resultAndRecursions :: a -> (a, Int)
resultAndRecursions a = (last (intermediates a), length (intermediates a) - 1)
-- you'd want to make your own safe function here, not use last and length
Run Code Online (Sandbox Code Playgroud)

或展开:

intermediates = unfoldr op
  where
  op a | terminationPred a = Nothing
       | otherwise = let a' = algorithm a
                     in Just (a', a')
Run Code Online (Sandbox Code Playgroud)

编辑:还注意到这两个中间体略有不同,因为第一个维持基本情况(输入a,因此- 1),而第二个不存在,因此在互补中会有微小的差异resultAndRecursions.

  • 哦,还有...... +1,感谢你在我迷惑自己之后加紧并给出了正确的答案.:\我今天喝的咖啡还不够. (2认同)