你好Haskellers先生。
我们说我有一个应用函子(不是monad的例子)我 想要多次应用于纯初始值。例如,
λ> Just (1+) <*> (Just (1+) <*> pure 0)
Just 2
如果我想将此概括为任意数量的连续
应用程序,我可以使用fold
。
applyAppl :: Applicative f => f (a -> a) -> Int -> f a -> f a
applyAppl f n i = foldr (<*>) i $ replicate n f
在此定义之后,
λ> applyAppl (Just (1+)) 10 $ pure 0
Just 10
我有一种尴尬的怀疑,即泛化也可能
使用其中一个高阶内置应用工具完成,例如sequenceA
或traverse
。可以吗?
(编辑考虑下面的前两条评论。)
答案 0 :(得分:3)
您可以使用iterate
:
applyAppl :: Applicative f => f (a -> a) -> Int -> f a -> f a
applyAppl f n i = iterate (f <*>) i !! n
加入GHCi:
ghci> applyAppl (Just (+1)) 10 (pure 0)
Just 10
我不确定它是否一定比你的实现更好,因为我怀疑这两种实现融合成具有基本相同性能的东西(尽管我还没有测试过),但它是不同。
我已经看到过这种&#34; iterate
与(!!)
&#34;记忆的模式,所以我很确定,至少,它的表现会更差。
答案 1 :(得分:0)
也许您正在寻找@David Young的答案的以下变体:
exit.clear()
,并提供:
foo :: Applicative f => f (a -> a) -> Int -> a -> f a
foo f n i = fmap (($ i) . iterateN n) f
where iterateN n f = (!! n) . iterate f
这使用Functor实例形式的“applicative machinery”,以便在不明确使用> foo (Just (1+)) 10 0
Just 10
>
的情况下执行功能迭代和应用程序。我不确定你还有什么希望在这里。