sequenceA如何在配对列表上工作?

问题描述

简化this问题。凭直觉,我已经了解了sequenceA在该用例中的作用,但 如何/为什么 那样工作。

因此,所有问题归结为一个问题:sequenceA在以下情况下如何工作?

> sequenceA [("a",1),("b",2),("c",3)]
("abc",[1,2,3])

我看到了

sequenceA :: (Traversable t,Applicative f) => t (f a) -> f (t a)

因此,在Traversable上方的用例中,[]Applicative,由于(,)是二进制类型的构造函数,因此(,) asnd,这意味着该对在其snd字段上被视为应用函子。这样一来,列表就以结果的"abc"结尾。因此,我们从成对的列表转到第二个字段中具有列表的对。

但是fst来自哪里?我的意思是,我知道这是所有对中++的串联,但是我不知道它是通过{{1}列表中的concat还是通过fst } s。 sequenceA的签名中似乎没有任何东西可以强制要求成对的fst可以组合在一起。

仍然必须在某个地方使用该假设。确实,以下失败

sequenceA [('a',('b',('c',3)]

解决方法

它使用mappend。它使用的Applicative实例如下所示:

instance Monoid a => Applicative ((,) a) where
    pure x = (mempty,x)
    (af,f) <*> (ax,x) = (mappend af ax,f x)
,

在Haskell中,某个类型的类型类实例可以在该类型的某些部分存在其他类型类实例的情况下成为“条件”。不是 all 类型的构造函数 ((,) a)形式的Applicative实例,但是类型为a的{​​{1}}实例。

这些必需的约束出现在实例的Haddock中的Monoid之前,如下所示:

=>

为什么需要Monoid a => Applicative ((,) a) 实例?例如,Monoid的{​​{1}}需要凭空实现一个pure值,以将其放入元组的第一个元素。类型为((,) a)的{​​{1}}可以完成工作。


可能存在许多层次的所需约束链。例如,为什么以下方法起作用?

a

第一个组件是函数。和以前一样,它必须具有mempty实例才能使a起作用。但是ghci> import Datta.Function ((&)) -- flipped application ghci> [(id :: String -> String,2 :: Int),(\x -> x ++ x,1)] & sequenceA & fst $ "foo" "foofoofoo" 类型何时为Monoid?看看黑线鳕,我们发现:

sequenceA

也就是说,当返回类型(此处为a -> b)为Monoid时,函数就是Monoid b => Monoid (a -> b)

实际上,还有一个{em> Monoid实例,这些实例可以通过Endo新类型使用。尽管需要一定数量的包装和展开,但通常使用newtypes选择用于给定操作的实例。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...