将函数 n 次应用于 haskell 列表中的第 n 项
apply a function n times to the n-th item in a list in haskell
我想要一个高阶函数 g,它会将另一个函数 f 应用于整数列表,使得
g = [f x1, f(f x2), f(f(f x3)), … , f^n(xn)]
我知道我可以映射一个像
这样的函数
g :: (Int -> Int) -> [Int] -> [Int]
g f xs = map f xs
我也可以像
一样应用n次函数
g f xs = [iterate f x !! n | x <- xs]
其中 n 是应用函数的次数。我知道我需要使用递归,所以我认为这些选项都没有用。
预期输出:
g (+1) [1,2,3,4,5] = [2,4,6,8,10]
您可以使用显式递归,每次都传递要应用的函数和列表的尾部,因此:
g :: (Int -> Int) -> [Int] -> [Int]
g f = go f
where go _ [] = []
go fi (x:xs) = … : go (f . fi) xs
我在这里将实现 …
部分作为练习。
另一种选择是使用两个列表,一个函数列表和一个值列表。在这种情况下,函数列表是 iterate (f .) f
:可以应用的无限函数列表。那么我们可以将g
实现为:
g :: (Int -> Int) -> [Int] -> [Int]
g f = zipWith ($) (iterate (f .) f)
听起来像是 foldr 的另一个用途:
applyAsDeep :: (a -> a) -> [a] -> [a]
applyAsDeep f = foldr (\x xs -> f x : map f xs) []
λ> applyAsDeep (+10) [1,2,3,4,5]
[11,22,33,44,55]
如果你想有点矫枉过正......
import GHC.Exts (build)
g :: (a -> a) -> [a] -> [a]
g f xs0 =
build $ \c n ->
let go x r fi = fi x `c` r (f . fi)
in foldr go (const n) xs0 f
我想要一个高阶函数 g,它会将另一个函数 f 应用于整数列表,使得
g = [f x1, f(f x2), f(f(f x3)), … , f^n(xn)]
我知道我可以映射一个像
这样的函数g :: (Int -> Int) -> [Int] -> [Int]
g f xs = map f xs
我也可以像
一样应用n次函数g f xs = [iterate f x !! n | x <- xs]
其中 n 是应用函数的次数。我知道我需要使用递归,所以我认为这些选项都没有用。
预期输出:
g (+1) [1,2,3,4,5] = [2,4,6,8,10]
您可以使用显式递归,每次都传递要应用的函数和列表的尾部,因此:
g :: (Int -> Int) -> [Int] -> [Int]
g f = go f
where go _ [] = []
go fi (x:xs) = … : go (f . fi) xs
我在这里将实现 …
部分作为练习。
另一种选择是使用两个列表,一个函数列表和一个值列表。在这种情况下,函数列表是 iterate (f .) f
:可以应用的无限函数列表。那么我们可以将g
实现为:
g :: (Int -> Int) -> [Int] -> [Int]
g f = zipWith ($) (iterate (f .) f)
听起来像是 foldr 的另一个用途:
applyAsDeep :: (a -> a) -> [a] -> [a]
applyAsDeep f = foldr (\x xs -> f x : map f xs) []
λ> applyAsDeep (+10) [1,2,3,4,5]
[11,22,33,44,55]
如果你想有点矫枉过正......
import GHC.Exts (build)
g :: (a -> a) -> [a] -> [a]
g f xs0 =
build $ \c n ->
let go x r fi = fi x `c` r (f . fi)
in foldr go (const n) xs0 f