【问题标题】:Use higher-order functions instead of explicit recursion使用高阶函数而不是显式递归
【发布时间】:2021-03-13 10:02:17
【问题描述】:

我想写一个函数f将二进制列表转换为整数,比如:

f :: [Integer] -> Integer
f [] = 0
f list = (last list) * 2^(length list -1) + f (init list)

例如f [1,1,1,1,0,0,1,0] = 79中,第一个列表元素代表2^0,最后一个列表元素代表2^7。

我可以用高阶函数而不是显式递归来编写这个函数吗?

【问题讨论】:

  • 是的,您可以使用foldl 完成此操作。
  • 这就是我的想法,但是我如何在 foldl 中处理(长度列表 -1)?
  • 忘记求幂和length。想想abcd = 1*d + 2*c + 2*2*b + 2*2*2*a = 1*d + 2*(c + 2*(b + 2*a)))
  • @Sambud_Ger:你不需要长度,如果你每次乘以2,然后加上值,最终得到2^n
  • molbdnilo 指的是Horner's method

标签: function haskell higher-order-functions


【解决方案1】:

您可以使用foldr :: Foldable f => (a -> b -> b) -> b -> f a -> b,它使用一个“折叠”函数,该函数接受一个元素和累加器。累加器在概念上从右到左在列表上运行。因此,您可以每次对累加器进行运算,然后添加元素的值:

f :: (Foldable f, Num a) => f a -> a
f = foldr g 0
    where g x acc = …

哪里还需要填写g

【讨论】:

    【解决方案2】:

    看起来你的列表顺序对于 foldl 来说是不幸的,但你可以像这样传递指数:

    intvalueOfList = fst . foldl f (0,1) 
       where f (acc,exp) e = (acc+e*exp, exp*2)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-22
      • 2021-10-24
      • 1970-01-01
      • 2014-08-16
      • 1970-01-01
      • 2020-04-04
      • 1970-01-01
      • 2016-02-22
      相关资源
      最近更新 更多