0

我正在尝试使用 haskell 类,我发现(至少某些)Traversable数据结构也是Applicative

当您查看 的定义时Traversable,您会发现它可以使用以下sequenceA函数定义:

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

由于listTraversableand Applicative,我确实尝试在列表列表中使用 sequenceA :

-- this thing ...
sequenceA [[0, 1], [7, 8, 9]]

-- is evaluated as [[0,7],[0,8],[0,9],[1,7],[1,8],[1,9]]

我得到了 2 个列表的笛卡尔积!

它甚至适用于更多的列表。


这是什么情况?

这个函数的行为背后的直觉是什么?

4

1 回答 1

3

列表应用的直觉是非确定性计算。您可以将[X]具有n 个元素的类型列表视为生成 的计算,X它绝对是该列表中包含的n 个选项之一X,但其中任何一个都是可能的。

例如,该列表['a','e']表示可以产生'a'或可能产生的计算'e'。该列表[-4,4]可能是询问 的平方根的结果16。该列表[]是一个不确定的计算,不能正确产生任何值!(比如说,询问...的实数平方根的结果-16

在这种解释中,当我们有一个函数列表fs和一些值xs时,该列表是通过将任何函数应用到 中的任何参数fs <*> xs可以获得的所有可能结果的列表。同时,列表是确定性计算,总是只产生一个结果,即.fsxspure xx

所以!如果您有一个嵌套列表,那么有多种不同的方式来思考它的含义,包括它是一个非确定性计算的列表,或者它是一个生成列表作为其结果的非确定性计算。该sequenceA函数在这些表示之间传输您:它接受一个不确定性计算的列表,并生成一个结果是一个列表的单个不确定性计算。所以:

 [[a,b,c],[d,e],[f,g,h,i]]

您可以将其视为包含三个元素的列表。第一个是在、、和之间的选择ab第二c个是在d和之间的选择,e第三个是在、、、和之间的选择。该函数将产生一个不确定的列表选择,每个列表的形状都与上面的外部列表相同;也就是说,我们在其中选择的每个列表的长度都是 3。第一个元素将来自; 第二个将来自,第三个来自。如果您考虑一下可能发生的所有方式,您会发现这正是他们的笛卡尔积!fghisequenceA[a,b,c][d,e][f,g,h,i]

于 2021-01-22T22:04:50.647 回答