Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 你能在Clojure中将插入排序表述为幺半群吗?_Sorting_Haskell_Clojure_Insertion Sort_Monoids - Fatal编程技术网

Sorting 你能在Clojure中将插入排序表述为幺半群吗?

Sorting 你能在Clojure中将插入排序表述为幺半群吗?,sorting,haskell,clojure,insertion-sort,monoids,Sorting,Haskell,Clojure,Insertion Sort,Monoids,这是Clojure中插入排序的代码: (排序中的定义![数据] (letfn[(插入([原始x](插入[]原始x)) ([已排序的[y&raw]x] (如果(无)(连词x) (if)(幺半群(olx)其中 mempty=OL[] mappend(OL xs)(OL ys)=OL(合并xs ys),其中 合并[]ys=ys 合并xs[]=xs 合并xs@(x:xs’)ys@(y:ys’) |x[x]>olx isort=折叠贴图(OL.pure) 要在Clojure中写入幺半群: (def me

这是Clojure中插入排序的代码:

(排序中的定义![数据]
(letfn[(插入([原始x](插入[]原始x))
([已排序的[y&raw]x]
(如果(无)(连词x)
(if)(幺半群(olx)其中
mempty=OL[]
mappend(OL xs)(OL ys)=OL(合并xs ys),其中
合并[]ys=ys
合并xs[]=xs
合并xs@(x:xs’)ys@(y:ys’)
|x[x]>olx
isort=折叠贴图(OL.pure)
要在Clojure中写入幺半群:

(def mempty(+));0
(def mappend+)
(定义mconcat[ms]
(减少mappend mempty ms))
(mappend 3 4);;7
(mconcat[2 3 4]);9

我的问题是:你能在Clojure中将插入排序公式化为幺半群吗?

这是我的尝试,但可能不是最好的:)

这是Haskell幺半群的直接翻译,因为Clojure中没有自动套用,所以我需要制作一个特殊的
comp-2
函数

(defn comp-2[f g]
(fn[xy](f(gx)(gy)))
(定义纯列表[x]
(续)
(顺序?x)(如果(空?x)“”()(顺序x))
:else(列表x)))
(def OL mempty(列表))
(除地图外)
(letfn[(合并[xs-ys]
(续)
(空?xs)ys
(空?ys)xs
:else(让[[x&xs']xs
[y&y']ys]

(这里的if(作为参考,是另一个版本,它使用累加器将尾部递归转换为尾部递归。为了多样性,这里还有一种方法可以部分模拟缺少的类型类

(def协议幺半群)
(记忆[_])
(mappend[xs ys]))
(defn)褶皱图
[幺半群f-xs]
(reduce(部分mappend幺半群)(mempty幺半群)(mapfxs)))

(定义-作战需求图)
[x&rx:as xs][y&ry:as ys]a]
(续)
(空?x)(concat a ys)
(空?ys)(concat a xs)
:else(如果(

(defn isort[xs](折叠地图命令列表xs))
(defn已排序?[xs](应用正确(稍后某个时候)

这很好。您应该将merge中的递归封装在惰性seq中,这样在对长序列进行排序时不会导致堆栈溢出。我已经在修复程序中进行了编辑,以便将一次编辑保存到社区Wiki状态(10),如果你不介意的话。深度递归的问题可能被未实现的惰性序列的堆叠所取代。我对Haskell了解不够,不知道它是否会有同样的问题。无论如何,这可以通过使用累加器轻松解决,因为这是尾部递归模a cons,但你的版本显示出与Haskell one。@在这些情况下,Willence在Clojure中通常也不会回避懒惰的缺点。在Clojure中,在没有强制严格要求的情况下,这在较大的输入上会失败,因为Thunk嵌套太深。如果您基于懒惰序列迭代构建懒惰序列,那么在强制执行r时可能会破坏堆栈随着恶棍链的瓦解,我怀疑哈斯克尔也是如此,因为你的“当心恶棍爆炸!”在这里发表评论。@A.Webb啊,这很尴尬。是的,当然,插入将强制使用正确的参数,即递归结果;因此,是的,这在Haskell中也是一个问题。即使插入不会强制使用正确的arg结束,但它至少需要一个元素,因此整个链将强制使用最后一个元素输入列表的ent。但这是排序,它必须强制通过所有的ELT以产生结果的头部…唯一的解决方案是将插入树重新排列为更平衡的形式,以限制thunk嵌套的深度。但随后它变为
mergesort
@A.Webb,因此对于插入排序,
foldr
公式是一场灾难;foldl
,正如您所说,严格性最好得到加强。haskell代码实现了合并排序,而不是插入排序。我不确定,但插入排序似乎不像合并排序那样具有单向结构。@amalloy不,它是插入排序,因为折叠树完全向右倾斜:
isortxs==foldr(merge.([]))[]xs
(即左侧列表始终为单例)。换句话说,它将集合映射为单子列表的集合,以便monoid处理。折叠然后将单子列表合并到累加器中。这与插入操作相同。您是否可以扩展您所说的“部分模拟缺失类型类的一种方法”@Haskell中的hawkeye monoid是一个类型类,一个c类型契约。正如你所知,Clojure在语言层面上避开了正式的类型系统(在语言层面上逐渐增加)。因此,你的一系列问题——“你能用Clojure中的typeclass Foo做X吗?”——回答起来有些尴尬。通常,最真实的答案是“是的,但你没有类型为什么还要麻烦?”或者,“这不是Clojure的惯用说法。"Clojure人倾向于在复杂性出现时使用自己的DSL来管理复杂性,而不是从一开始就采用形式主义。@Haskell中的hawkeye类型类在多态性方面非常强大。在Clojure中,我们认为很多多态性是理所当然的,因为我们不必费心指定类型。但是,有协议和多种方法。这些功能非常强大,但不如Haskell的typeclass强大。您可以通过在协议中指定约定来引入类似typeclass的功能。这只会在第一个参数上分派,而Haskell可以分派整个签名,包括返回值。多方法比协议更强大,但不如powerfu作为Haskell的分派。@hawkeye所以,这里我使用了一个伪第一个参数来分派我想要的那种幺半群