对参数应用函数 x 次的函数

dan*_*oly 2 haskell higher-order-functions

编写一个doItX :: (a -> a -> a) -> a -> Int -> a函数,将第一个参数乘以f x第二个参数。

doItX (*) 2 1 == 2

doItX (++) "a" 6 == "aaaaaa"

doItX (*) 2 3 == 8
Run Code Online (Sandbox Code Playgroud)

我有以下代码:

doItX f a x
  | x==1 = a
  | x>1 = doItX f (f a a) (x-1)
Run Code Online (Sandbox Code Playgroud)

如果 是 2 或更小,则效果很好x,但对于第三个示例,它返回16而不是8

jpm*_*ier 5

可能最惯用的\xe2\x80 \x9c 解决方案是基于库的解决方案:

\n
doItX1 :: (a -> a -> a) -> a -> Int -> a\ndoItX1 f a x = foldr1 f (replicate x a)\n
Run Code Online (Sandbox Code Playgroud)\n

此处记录了Prelude函数foldr1

\n

但是,如果由于您的某种原因,您坚持使用手动递归,那么您的代码就差不多了。您只需要修复递归调用:

\n
doItX :: (a -> a -> a) -> a -> Int -> a\ndoItX f a x\n  | (x > 1)    =  ----Was: doItX f (f a a) (x-1)\n                  f a (doItX f a (x-1))\n  | (x == 1)   =  a\n  | otherwise  =  error ("doItX called with x set to " ++ (show x))\n
Run Code Online (Sandbox Code Playgroud)\n

  • IMO `iterate` 比 `foldr1` 更惯用:`doItXfax = iterate (fa) a !! (x - 1)` (3认同)