你好Haskellers先生.
假设我有一个applicative functor(不是monad的实例)我想多次应用于纯初始值.例如,
?> Just (1+) <*> (Just (1+) <*> pure 0)
Just 2
Run Code Online (Sandbox Code Playgroud)
如果我想将它推广到任意数量的连续应用程序,我可以使用a fold.
applyAppl :: Applicative f => f (a -> a) -> Int -> f a -> f a
applyAppl f n i = foldr (<*>) i $ replicate n f
Run Code Online (Sandbox Code Playgroud)
在这个定义之后,
?> applyAppl (Just (1+)) 10 $ pure 0
Just 10
Run Code Online (Sandbox Code Playgroud)
我有一种尴尬的怀疑,即可以使用其中一个高阶内置应用工具来完成泛化,例如sequenceA或traverse.它可以?
(编辑考虑下面的前两条评论.)
你可以使用iterate:
applyAppl :: Applicative f => f (a -> a) -> Int -> f a -> f a
applyAppl f n i = iterate (f <*>) i !! n
Run Code Online (Sandbox Code Playgroud)
加载到 GHCi 中:
ghci> applyAppl (Just (+1)) 10 (pure 0)
Just 10
Run Code Online (Sandbox Code Playgroud)
我不确定这一定比您的实现更好,因为我怀疑这两种实现都融合成具有基本相同性能配置文件的东西(尽管我还没有测试过),但它是不同的。
我见过这种“ iteratewith (!!)”模式的记忆,所以我很确定,至少,它不会有更差的性能。