基本的Haskell:通过递归定义排序函数

时间:2016-01-19 16:55:51

标签: haskell

所以我的排序功能有点问题。我需要定义(使用递归)函数 i ,它将参数列表 a 作为参数(此列表需要属于 Ord >),输出 a 类型的有序元素列表。 例: 我[3,2,1] = [1,2,3]

我设法提供了这个解决方案:

i :: Ord a => [a] -> [a]

i [] = []
i (x:xs) 

| x <= head (xs) = x: i xs
| otherwise = i xs : x

但是它没有计算,输出很多错误。怎么了?

1 个答案:

答案 0 :(得分:4)

让我给你一些提示,让你开始。首先,让我们修复格式:

i :: Ord a => [a] -> [a]
i [] = []
i (x:xs) 
    | x <= head (xs) = x: i xs
    | otherwise = i xs : x

这会抛出一个错误,上面写着:

In the first argument of ‘(:)’, namely ‘i xs’
In the expression: i xs : x

现在,这个表达式i xs : x存在问题。 (:)的类型为(:) :: a -> [a] -> [a]。但是在表达式中,您传递的是列表而不是值。您打算使用的可能是++。使用它修复了编译错误:

i :: Ord a => [a] -> [a]
i [] = []
i (x:xs)
    | x <= head (xs) = x: i xs
    | otherwise = i xs ++ [x]

现在,如果你在ghci中试用它,你将得到一个运行时异常:

ghci> i [3,2,1]
*** Exception: Prelude.head: empty list
你能猜到为什么吗?那是因为您没有处理列表长度为1的情况。所以处理这个案子会给你这个:

i :: Ord a => [a] -> [a]
i [] = []
i (x:[]) = [x]
i (x:xs)            
    | x <= head (xs) = x: i xs
    | otherwise = i xs ++ [x]

现在,您可能认为这有效:

ghci> i [3,2,1]
[1,2,3]
ghci> i [3,1,2]
[1,2,3]

但它实际上并不起作用,因为你的算法存在缺陷。只比较列表的前两个元素就不会给你一个排序的数组。

ghci> i [2,1,3]
[1,3,2]

我希望这足以让你开始。