为什么列表仿函数代表了非确定性选择的上下文?

时间:2012-04-18 21:11:12

标签: haskell functional-programming

这句话是什么意思?

the list functor represents a context of nondeterministic choice;

在函数式编程的Functors环境中。

我认为我理解Functor是某种“容器”,并且能够在不改变结构的情况下将函数统一地应用于容器中的元素。所以也许是一个Functor代表一个可能失败的上下文或容器,但为什么list代表一个具有非确定性选择的上下文或容器?

5 个答案:

答案 0 :(得分:11)

据我所知,如果计算有多个可能的答案,那么计算就是“不确定的”。好吧,列表可以包含多个可能的答案。这就是原因。

(至于为什么它被称为非确定性,我不知道......我本来期望非确定性意味着随机,这是完全不同的。)

答案 1 :(得分:8)

传统上,在可计算性和复杂性方面,非确定性计算模型已经引用了一个模型,在这种情况下你可以“分支”。维基百科解释如下:

  

在计算复杂性理论中,非确定性算法是指在每个可能的步骤中都可以允许多个连续的算法(想象一个人走在森林中的路径上,每次他走得更远,他必须选择哪个叉子他希望走的路)。这些算法没有为每个可能的计算路径找到解决方案;然而,他们保证能够为某些路径找到正确的解决方案(即,如果他选择“正确”路径的某种组合,那么穿过森林的人可能只能找到他的小屋)。选择可以解释为搜索过程中的猜测。

在monad列表中,这正是您正在做的事情。例如,在列表monad中考虑clique problem的决策版本的此解决方案:

cliques :: Int -> Graph -> [[Node]]
cliques 0 _ = [[]]
cliques minCliqueSize graph = do
  v <- nodes graph
  vs <- cliques (minCliqueSize - 1) (deleteNode v graph)
  mapM_ (\ w -> guard (isAdjacent v w graph)) vs
  return (v:vs)

这正是您编程的方式,例如一个不确定的图灵机来解决集团问题。

答案 2 :(得分:5)

请考虑以下事项:

foo = do
  x <- [1 .. 10]
  y <- [2, 3, 5, 7]
  return (x * y)

什么是foo?好吧,它是x * y,除了x的非确定性选择是从1到10的数字,y是2,3,5或7.因此,foo是{{1} }

答案 3 :(得分:5)

除了将仿函数视为容器外,您还可以将其视为某种上下文。您的值在该上下文中,如果您想对它们进行操作,则使用map将函数提升到上下文中。另一种表达方式是使用该上下文扩充您的值。

要理解列表仿函数是非确定性选择的上下文,了解另一个仿函数是如何成为上下文可能很有用:Maybe仿函数是可能失败的计算的上下文。如果您尝试将函数应用于Maybe仿函数中的值,则结果值仍将保持相同的上下文,无论它是否是一个失败的计算。

以同样的方式,列表可以看作是没有确定性结果的计算结果,但是其结果可能是从几个值中的一个不确定地选择的。如果您尝试在具有3个元素的列表上映射函数,那么这些元素将会更改,但是能够在三个值之间进行选择的上下文将保持不变。

从Dan Burtons那里借一点回答,看一下列表中的monadic符号:

foo = do
  x <- [1 .. 10]
  y <- [2, 3, 5, 7]
  return (x * y)

起初看起来有点奇怪,因为符号似乎表明,您可以从每个列表中提取单个值,但随后您会得到一个长度为40个元素的列表。当你将functor(在这种情况下,monad)看作单个值的上下文时,它会更有意义。在示例中,xy是这样的值,但它们的上下文是它们是不确定的。当您将两个这样的值相乘时,您会得到更多的不确定性,从而导致列表更长。因此,对于monad和>>=,可以更改上下文,而使用functor和map则不能。

答案 4 :(得分:4)

“经典”计算需要1个输入并给出1个输出。 您希望用这些非确定性计算表示的是:如果我不确定输入,我可以对输出说些什么?

表示不确定性的两种常用方法是考虑:

  1. 输入是给定集合的元素
  2. 输入由已知概率分布给出
  3. 例如,考虑将输入加倍的函数(2 *)。 当输入是模具滚动的结果时,您对该功能的输出有什么看法?

    1. 我知道骰子有6个面,因此结果在集合{2,4,6,8,10,12}
    2. 我知道每张脸的概率是1/6,所以我知道这些数字中的每一个都有1/6的概率出现
    3. 列表仿函数表示1的意义上的非确定性计算:它表示按列表设置。