多次应用applicative functor的方法

时间:2017-12-05 05:59:13

标签: haskell

你好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

我有一种尴尬的怀疑,即泛化也可能 使用其中一个高阶内置应用工具完成,例如sequenceAtraverse。可以吗?

(编辑考虑下面的前两条评论。)

2 个答案:

答案 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 > 的情况下执行功能迭代和应用程序。我不确定你还有什么希望在这里。