Sorting Haskell简单初学者排序程序
哈斯克尔还是个新手。我正在尝试使用递归编写排序函数,到目前为止,我已经做到了:Sorting Haskell简单初学者排序程序,sorting,haskell,Sorting,Haskell,哈斯克尔还是个新手。我正在尝试使用递归编写排序函数,到目前为止,我已经做到了: sort' :: [Int] -> [Int] sort' [] = [] sort' [x] = [x] sort' (x:y:xs) = if x > y then y:sort' (x:xs) else x:sort' (y:xs) 据我所知,当要排序的元素少于2个时,它可以正常工作。但是如果我输入[3,2,1],我得到[2,1,3]。我已经尝试手动跟踪输入的路径,但我不知道
sort' :: [Int] -> [Int]
sort' [] = []
sort' [x] = [x]
sort' (x:y:xs) =
if x > y
then y:sort' (x:xs)
else x:sort' (y:xs)
据我所知,当要排序的元素少于2个时,它可以正常工作。但是如果我输入[3,2,1],我得到[2,1,3]。我已经尝试手动跟踪输入的路径,但我不知道如何对2个以上的初始元素进行排序。我读了一些书,并且考虑了一些涉及到迭代和使用列表长度(
length
)的事情,但是我不确定如果它真的起作用,如何实现它。你的排序'
实现了冒泡排序的迭代,因此,反复应用它将得到一个完全排序的列表。有,一个是使用迭代
重复应用它,然后使用选择第N个应用程序代码>:
completeSort list = iterate sort' list !! length list
您的sort'
实现了冒泡排序的迭代,因此反复应用它将产生一个完全排序的列表。有,一个是使用迭代
重复应用它,然后使用选择第N个应用程序代码>:
completeSort list = iterate sort' list !! length list
正如@另一个家伙指出的,您可以使用iterate
将sort'
应用于列表n
次,这是在Haskell中使用高级组合符的一个很好的例子(与原始递归相反)。另一个对这类事情有用的很好的组合词是until
:until
将接受谓词::a->Bool
、函数::a->a
、值::a
,并将函数应用于该值,直到谓词保持为真。因此,当您遇到类似的情况,但不知道要对输入进行多少次传递时,可以执行类似于的操作,直到IsOrted sort'xs
,这非常好
Haskell中还有很多其他单次排序算法,包括自顶向下和(尤其是)自底向上的合并排序
冒着让你陷入理论深渊的风险,我想提到另一种非常好的高级组合思维方式,即迭代n次。这是基于“递归模式”的思想,其基本思想是递归数据类型的结构通知处理/转换它的有用模式。恰巧,哈斯克尔的能力足以表达这些想法。递归方案的最简单示例之一是基于自然数:
data Nat = Zero | Succ Nat
这是一种递归数据类型,因为第二个数据构造函数引用回Nat
本身。有一种处理Nat
s的非常自然的方法,也就是说:当我有Zero
时,我应该返回一些值;否则,我应该递归地处理Nat
,然后使用这些值生成一个新值。事实上,我们可以用不同的方式编写Nat
,这使得一般来说非常容易做到:
data NatF a = Zero | Succ a
type Nat = Mu NatF
现在,NatF
数据类型可以在其“递归”组件中保存任何类型的值,而不仅仅是另一个Nat
。第二行中的Mu
类型构造函数基本上类似于fix
函数,但对于类型:它实例化NatF(NatF(NatF(NatF…))
,因此Nat=NatF-Nat
,这与我们之前的定义相同
但是,由于泛型的增加,我们现在可以写下描述处理Nat
s的函数的类型:natfa->a
。当给定一个0
时,这种类型的函数只返回一些a
;当给定一个Succ
时,它可以访问它在“内部”Nat
上递归调用时返回的a
。事实证明,可以对实现这一点所需的基础设施进行泛化,这样它就可以处理以上述样式编写的任何类型(即,作为递归组件上泛化的类型的固定点)。这意味着您可以在给定递归调用结果的情况下,为函数写下方程式,然后在此数据结构上调用cata
,而不必费心写下重复的无聊递归调用
这还意味着将“应用排序”(长度xs)时间写入xs`的另一种方法是:
sort xs = cata phi (toNat $ length xs)
where phi Zero = xs
phi (Succ xs) = sort' xs
正如@另一个家伙指出的,您可以使用iterate
将sort'
应用于列表n
次,这是在Haskell中使用高级组合符的一个很好的例子(与原始递归相反)另一个对这类事情有用的很好的组合词是直到:直到将接受一个谓词::a->Bool
,一个函数::a->a
,一个值::a
,并将函数应用于该值,直到谓词保持为真。因此,当您遇到类似情况但不知道e时确切地说,您希望对输入进行多少次传递,您可以执行类似于的操作,直到isSorted sort'xs
,这非常好
Haskell中还有很多其他单次排序算法,包括自顶向下和(尤其是)自底向上的合并排序
冒着让你陷入理论深渊的风险,我想提到另一种关于迭代n
次的非常好的高级组合思维方式。这是基于“递归方案”的思想,其基本思想是递归数据类型的结构通知处理/转换它的有用模式。恰巧,哈斯克尔的能力足以表达这些想法。递归方案的最简单示例之一是基于自然数:
data Nat = Zero | Succ Nat
这是一种递归数据类型,因为第二个数据构造函数引用回Nat
本身。有一种非常自然的方式