简体   繁体   English

使用高阶函数而不是显式递归

[英]Use higher-order functions instead of explicit recursion

I want to write a function f that converts a binary list to an integer, like:我想编写一个 function f将二进制列表转换为 integer,例如:

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

For example, in f [1,1,1,1,0,0,1,0] = 79 , the first list element represents 2^0 and the last list element represents 2^7.例如,在f [1,1,1,1,0,0,1,0] = 79中,第一个列表元素表示 2^0,最后一个列表元素表示 2^7。

Can I write this function with higher-order functions instead of with explicit recursion?我可以用高阶函数而不是显式递归来编写这个 function 吗?

It appears the order of your list is unfortunate for foldl, but you can pass the exponent along like so:看来你的列表顺序对 foldl 来说是不幸的,但你可以像这样传递指数:

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

You can make use of foldr:: Foldable f => (a -> b -> b) -> b -> fa -> b which uses a "folding" function that takes an element and the accumulator.您可以使用foldr:: Foldable f => (a -> b -> b) -> b -> fa -> b ,它使用带有元素和累加器的“折叠” function。 The accumulator conceptually runs right-to-left over the list.累加器在概念上在列表上从右到左运行。 You can thus each time souble the accumulator and then add the value of the element:因此,您可以每次对累加器进行 souble,然后添加元素的值:

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

where you still need to fill in g .你仍然需要填写g的地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM