【问题标题】:is the fix function a better way to replace while loops?修复函数是替换 while 循环的更好方法吗?
【发布时间】:2021-12-29 20:06:21
【问题描述】:

当您在 do 块中时,为了模拟“while 循环”,通常会看到人们在 let 语句中声明“循环”函数。但是,有一个聪明的函数“修复”,它允许您同时声明和使用该函数

main = do
   let fac n r = if n == 1 then r else fact (n-1) (n*r)
   print $ fact 4 1 -- 24
   
   print $ fix (\rec n r -> if n == 1 then r else rec (n-1) (n*r)) 4 1

问题是,fix 比使用 let 语句有什么优势吗? 是更慢还是使用更多内存?

【问题讨论】:

  • 我隐约记得在某处读到 GHC 在优化非递归函数方面比递归函数做得更好。 (这里的“递归”是对其静态属性的引用;fix 的参数本身不是递归的,因为它调用作为其第一个参数传递的任何函数,不一定是它自己。)

标签: haskell recursion


【解决方案1】:

不,没有优势。它甚至被实现为let 表达式:

fix f = let x = f x in x

【讨论】:

  • 这不是为一些内联打开了机会吗?不确定总体成本是否会更好。
  • @pedrofurla 我不确定你的意思。你能扩大一点吗?特别是,我不知道fix 如何打开一个内联let 无法打开的机会,因为正如答案中提到的那样,fix @987654326 @.
  • 作为进一步确认,如果您使用ghc -O2 -ddump-simpl -dsuppress-all 编译原始问题中的示例代码,GHC 会将两个版本合并为单个值/定义main2,它只是打印两次。
猜你喜欢
  • 2019-05-02
  • 2013-06-28
  • 2018-08-06
  • 2019-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多