sequenceA如何处理对列表? [英] How does sequenceA work on lists of pairs?

查看:62
本文介绍了sequenceA如何处理对列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题中解脱出来.凭直觉,我已经理解了sequenceA在该用例中的作用,但没有理解 如何/为什么 那样工作.

Spin off of this question. Intuitively I have understood what sequenceA does in that usecase, but not how/why it works like that.

因此,这全都归结为这个问题:sequenceA在以下情况下如何工作?

So it all boils down to this question: how does sequenceA work in the following case?

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

我看到了

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

因此,在Traversable以上的用例中,[][],而Applicative(,) a,这是因为(,)是二进制类型的构造函数,这意味着该对被用作应用函数.其snd字段.这一起将列表放在结果的snd中.因此,我们从成对的列表转到第二个字段中具有列表的成对.

so in the usecase above the Traversable is [], and the Applicative, since (,) is a binary type constructor, is (,) a, which means that the pair is taken as an applicative functor on its snd field. And this goes together the list ending up in the snd of the result. So we go from a list of pairs to a pair with a list in its second field.

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

But where does the "abc" come from? I mean, I know that it's the concatenation of the fst of all the pairs, but I don't know if it's via ++ or via concat of the list of the fsts. There seems to be nothing in sequenceA's signature to enforce that the fsts of the pairs can be combined together.

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

Still that assumption has to be used somewhere. Indeed, the following fails

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

推荐答案

在Haskell中,某个类型的typeclass实例可以是有条件的".关于类型部分是否存在其他类型类实例.不是 all 类型的构造函数 ((,) a)形式的ApplicativeApplicative的实例,但是那些a类型具有Monoid实例的实例.

In Haskell, typeclass instances for a type can be "conditional" on the existence of other typeclass instances for parts of the type. Not all type constructors of the form ((,) a)are instances of Applicative, but only those for which the a type has a Monoid instance.

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

These required constraints appear before the => in the instance's Haddocks, like this:

Monoid a => Applicative ((,) a)

为什么需要Monoid实例?例如,((,) a)pure需要凭空实现a值以放入元组的第一个元素. mempty用于类型a可以完成工作.

Why is the Monoid instance required? For one, pure for ((,) a) needs to materialize an a value out of thin air to put in the first element of the tuple. mempty for the type a does the job.

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

There can be chains of required constraints that are several levels deep. For example, why does the following work?

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类型?看看黑线鳕,我们发现:

Here the first component is a function. As before, it must have a Monoid instance for the sequenceA to work. But when is the type a -> b a Monoid? Looking at the Haddocks, we find:

Monoid b => Monoid (a -> b)

也就是说,当返回类型(此处为String)为Monoid时,函数为Monoid.

That is, functions are Monoids when the return type (here String) is a Monoid.

实际上,还有一个另一个 Monoid实例,这些实例可通过

Actually, there's another Monoid instance for functions available through the Endo newtype. It's common to use newtypes to select which instance to use for a given operation, although it requires some amount of wrapping and unwrapping.

这篇关于sequenceA如何处理对列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆