Haskell中的Random-Pivot Quicksort
是否可以在Haskell中实现快速排序(使用RANDOM-PIVOT)仍然具有简单的
Ord a => [a]->[a]
签名?
我开始理解Monads了,而且,就像现在一样,我将monad解释为像'命令模式'这样的东西,这对于IO非常有用。
所以,我理解一个返回随机数的函数实际上应该返回一个像IO一样的monadic值,因为否则会破坏引用透明性。我也明白,应该没有办法从返回的monadic值中“提取”随机整数,否则,它会再次破坏参照透明度。
但是,我仍然认为应该可以实现'纯'[a]->[a]
快速排序功能,即使它使用随机数据透视,因为它是参考透明的。从我的角度来看,随机数据透视只是一个实现细节,不应该改变函数的签名
OBS:我对具体的快速排序问题并不感兴趣(所以,我不想听起来很粗鲁,但我不是在寻找“使用mergesort”或“随机支点不会提高实践中的表现”这种答案)我实际上对如何实现一个在其中使用'impure'函数的'纯'函数感兴趣,例如quicksort,我可以确保函数实际上是纯函数。
Quicksort就是一个很好的例子。
没有找到相关结果
已邀请:
4 个回复
辅奈
中的函数
。 例如,您可以使用
获得初始随机状态,然后使用此状态执行任何操作。 但请注意:如果不是真的需要,请不要使用它。即便如此,请三思而后行。
在某种程度上是所有邪恶的根源,因为它的后果可能是戏剧性的 - 任何东西都可以通过强制使用此函数来强制使用不同的类型来破坏RTS。
莽缓逢
在这种情况下,枢轴的选择将决定卡的最终排序。以完全相同的方式 对于像这样的功能
是由a决定的。如果你是随机选择某些东西,那么你的计算是或者可能是非确定性的。
凸晴
好的,现在我们可以列出任何
并将其变成
。我在这里提供了
和
实例,更多更好的实例在可清洗的包装中,这也允许腌制和东西。 这就是我们可以做一个数字生成器。
所以现在有趣的部分。让我们编写一个带有随机数生成器,比较器函数和列表的函数。然后我们将通过查询生成器选择一个数据透视表来对列表进行排序,并使用比较器对列表进行分区。
库功能:
从发电机抓取一个
,并产生一个新的发电机。
将发电机分成两个不同的发电机。 我的功能:
使用
将列表分成三个列表。如果你知道褶皱,那应该很清楚。 (请注意,它不会保留子列表中元素的初始顺序;它会反转它们。使用折叠器可以解决这个问题。)
就像我之前说过的那样:咨询生成器的枢轴,分区list,fork生成器用于两个递归调用,递归地对左侧和右侧进行排序,并将它们连接在一起。 便利功能很容易从这里组成
注意最终函数的签名。
列表中的类型必须同时实现
和
。你需要的是“纯粹”的功能,有一个合乎逻辑的附加要求。更一般的功能对其要求的限制较少。
最后的笔记 对于所有输入,
的行为方式完全相同。 “随机”枢轴选择是。事实上,确定性。但它通过散列列表然后播种随机数生成器来模糊,使其对我来说足够“随机”。 ;)
也适用于长度小于
的列表,ghci告诉我的是9,223,372,036,854,775,807。我认为负面索引会出现问题,但在我的临时测试中我还没有碰到它。 或者,您可以使用IO monad来获得“更真实”的随机性。
嘘伪