这句话是什么意思?
the list functor represents a context of nondeterministic choice;
在函数式编程的Functors环境中。
我认为我理解Functor是某种“容器”,并且能够在不改变结构的情况下将函数统一地应用于容器中的元素。所以也许是一个Functor代表一个可能失败的上下文或容器,但为什么list代表一个具有非确定性选择的上下文或容器?
答案 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)看作单个值的上下文时,它会更有意义。在示例中,x
和y
是这样的值,但它们的上下文是它们是不确定的。当您将两个这样的值相乘时,您会得到更多的不确定性,从而导致列表更长。因此,对于monad和>>=
,可以更改上下文,而使用functor和map
则不能。
答案 4 :(得分:4)
“经典”计算需要1个输入并给出1个输出。 您希望用这些非确定性计算表示的是:如果我不确定输入,我可以对输出说些什么?
表示不确定性的两种常用方法是考虑:
例如,考虑将输入加倍的函数(2 *)。 当输入是模具滚动的结果时,您对该功能的输出有什么看法?
列表仿函数表示1的意义上的非确定性计算:它表示按列表设置。