遍历对应用上下文意味着什么?

时间:2019-04-05 10:19:18

标签: haskell applicative monoids traversable foldable

我试图借助https://namc.in/2018-02-05-foldables-traversals来了解Traversable。

作者在某处提到了以下句子:

  

Traversable对应用上下文而言是Foldable对Monoid   价值观。

他试图澄清什么?

我没有在Foldable to Monoid之间建立联系。

请提供示例。

2 个答案:

答案 0 :(得分:8)

开始时有foldr

foldr :: (a -> b -> b) -> b -> [a] -> b

mapM

mapM :: Monad m => (a -> m b) -> [a] -> m [b]
通过让每种类型定义foldr自己的定义来描述如何将其减少为单个值,将

[a]推广到foldr以外的数据类型。

-- old foldr ::        (a -> b -> b) -> b -> [] a -> b
foldr :: Foldable t => (a -> b -> b) -> b -> t  a -> b

如果有一个monoid,则不必指定一个二进制函数,因为Monoid实例已经提供了自己的起始值,并且知道如何组合两个值,这在其默认定义中显而易见。 foldr的条款:

-- If m is a monoid, it provides its own function of type b -> b.
foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
foldMap f = foldr (mappend . f) mempty

Traverse进行从列表到可遍历类型的相同类型的概括,但对于mapM

-- old mapM ::              Monad m        => (a -> m b) -> [] a -> m ([] b)
traverse :: (Traversable t, Applicative f) => (a -> f b) -> t  a -> f (t  b)

(第一次定义mapM时,没有Applicative类;如果有,则可以定义mapA :: Applicative f => (a -> f b) -> [a] -> f [b]Monad约束比是必要的。)

Applicative本质上是单调的,因此Traverse中不需要foldr / foldMap得出的区分类型。

答案 1 :(得分:0)

本文(和the corresponding passage of the Wikibook)讨论的是如何将应用值的效果(或使用此处看到的语言,上下文)进行单调组合。与Foldable的联系在于,类似列表的折叠最终最终等于将值进行单值组合(请参见chepner's answer,以及Foldr/Foldl for free when Tree is implementing Foldable foldmap?。至于应用上下文部分,有几种方法可以看一下这一点,其中之一是,对于任何Applicative fMonoid mf m是一个等边线,pure memptymempty,{{1 }}作为liftA2 mappendthis Ap type from the reducers package的见证)。举一个具体的例子,让我们选择mappendf ~ Maybe,这为我们提供了四种可能的组合:

m ~ ()

现在与AllliftA2 mappend (Just ()) (Just ()) = Just () liftA2 mappend (Just ()) Nothing = Nothing liftA2 mappend Nothing (Just ()) = Nothing liftA2 mappend Nothing Nothing = Nothing Bool的{​​{1}} id半体形成对比:

(&&)

它们完全匹配:mappend代表mappend (All True) (All True) = All True mappend (All True) (All False) = All False mappend (All False) (All True) = All False mappend (All False) (All False) = All False Just ()代表TrueNothing代表False

现在让我们再看一下Wikibook示例:

liftA2 mappend
(&&)

通过将deleteIfNegative :: (Num a, Ord a) => a -> Maybe a deleteIfNegative x = if x < 0 then Nothing else Just x rejectWithNegatives :: (Num a, Ord a, Traversable t) => t a -> Maybe (t a) rejectWithNegatives = traverse deleteIfNegative 应用于列表中的值而生成的GHCi> rejectWithNegatives [2,4,8] Just [2,4,8] GHCi> rejectWithNegatives [2,-4,8] Nothing 值按照上面显示的方式进行单项合并,因此除非得到 all ,否则我们将获得Maybe deleteIfNegative的值为Nothing

这个问题也可以朝相反的方向解决。通过Maybe的{​​{1}}实例...

Just

...我们可以从任何Applicative中得到一个Const,这样-- I have suppressed a few implementation details from the instance used by GHC. instance Monoid m => Applicative (Const m) where pure _ = Const mempty Const x <*> Const y = Const (x `mappend` y) 就会单边组合单边值。这样就可以define foldMap and friends in terms of traverse

最后一点,Applicative作为类单曲面函子的类的理论描述涉及的内容与我在此介绍的内容截然不同。有关此问题和其他精美印刷品的进一步讨论,请参见Monoidal Functor is Applicative but where is the Monoid typeclass in the definition of Applicative?(如果您想更深入地研究,这里的所有答案都是值得的。)