任何人都可以解释(更好地使用简单的英语示例)列表monad可以做什么来模拟非确定性计算?即问题是什么以及列表monad可以提供什么解决方案。
答案 0 :(得分:37)
这是一个基于抛硬币的例子。问题如下:
您有两个硬币,标有有偏见和 Fair 。 Biased 硬币有两个头, Fair 硬币有一个头和一个尾。随机选择其中一个硬币,扔掉并观察结果。如果结果是头部,那么您选择偏见硬币的概率是多少?
我们可以在Haskell中对此进行建模,如下所示。首先,你需要硬币及其面孔的类型
data CoinType = Fair | Biased deriving (Show)
data Coin = Head | Tail deriving (Eq,Show)
我们知道抛出一枚公平的硬币可能会出现Head
或Tail
,而有偏见的硬币总会出现Head
。我们用可能的替代方案列表对此进行建模(隐含地,每种可能性都是可能的)。
toss Fair = [Head, Tail]
toss Biased = [Head, Head]
我们还需要一个能够随机选择公平或有偏见的硬币的功能
pick = [Fair, Biased]
然后我们像这样把它们放在一起
experiment = do
coin <- pick -- Pick a coin at random
result <- toss coin -- Toss it, to get a result
guard (result == Head) -- We only care about results that come up Heads
return coin -- Return which coin was used in this case
请注意,虽然代码读起来就像我们只是运行一次实验,但是列表monad正在建模非确定性,并实际上遵循所有可能的路径。因此结果是
>> experiment
[Biased, Biased, Fair]
因为所有可能性都是同等可能的,我们可以得出结论,我们有2/3的机会拥有有偏见的硬币,只有1/3的机会我们拥有公平的硬币。
答案 1 :(得分:17)
当我们说它是非决定论时,它意味着它有多个值。
Learn You A Haskell书很好地解释了这一点:
像5这样的值是确定性的。它只有一个结果,我们知道 到底是什么。另一方面,像[3,8,9]这样的值包含 几个结果,所以我们可以将其视为一个实际上很多的值 价值在同一时间。使用列表作为applicative functor展示 这种非决定论很好:
ghci> (*) <$> [1,2,3] <*> [10,100,1000]
[10,100,1000,20,200,2000,30,300,3000]
左侧乘法元素的所有可能组合 包含右侧列表中元素的列表包含在结果中 名单。在处理非决定论时,有很多选择 我们可以做,所以我们只是尝试所有这些,结果是一个 非确定性的价值,只有它有更多的结果。
很好地列出monad模型非确定性。它的实例是这样的:
instance Monad [] where
return x = [x]
xs >>= f = concat (map f xs)
fail _ = []
因此,当您提供非确定性值时,它将产生另一组非确定性值:
ghci> [3,4,5] >>= \x -> [x, x * 2]
[3,6,4,8,5,10]
答案 2 :(得分:10)
列表monad可以表示“来自非确定性计算的所有可能结果”。例如,函数
f x = [x, x + 1, x + 2]
可以解释为一个非确定性计算,它采用x
并返回x
,x+1
和x+2
之一。
功能
g x = [2 * x, 3 * x]
可以解释为一个非确定性计算,它采用x
并返回2 * x
或3 * x
。这两个非确定性计算的“组成”应该是另一个非确定性计算,它采用x
,将其转换为x
,x + 1
或x + 2
之一,然后将它加倍或三倍。因此,就列表而言,结果应该是所有六种可能性的列表
现在
g =<< f x = [2 * x, 3 * x, 2 * (x + 1), 3 * (x + 1), 2 * (x + 2), 3 * (x + 2)]
所以这确实模仿了我们所期望的非决定论。
(使用列表进行非确定性有一些尴尬,因为它们也有元素的排序。“set monad”可能是一种更自然的非确定性建模方法。列表当然包含 用于建模非确定性的信息,但排序意味着我们有更多信息而不是必要的。)
编辑:实际上我写的只是使用列表应用实例。要获得完全利用monadic接口的东西,您需要一个返回大量结果的计算,这些结果取决于其输入,例如g 0 = [1000, 1001]
g x = [2 * x, 3 * x, 4 * x]
虽然承认这是一个完全随意且无动机的例子!
答案 3 :(得分:9)
因此,明确定义'非确定性'在这里意味着什么是很重要的,因为它与在非确定性算法中可能被感知的方式不完全相同。这里捕获的意义是计算分支 - 可能有多个状态,系统可以在任何特定点移动。
列表对此进行建模,因为它们只包含多个元素。更重要的是,monadic理解为我们提供了一种组合非确定性结果的方法 - 即模拟一次探索所有分支。