我正在尝试使用where
实现快速排序。在LYAH快速排名是使用let … in …
:
quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) =
let smallerOrEqual = [a | a <- xs, a <= x]
larger = [a | a <- xs, a > x]
in quicksort smallerOrEqual ++ [x] ++ quicksort larger
我使用where
的版本非常相似,但不起作用:
quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs)
| head(xs) >=x = head(xs):rightlist
| otherwise = head(xs):leftlist
where quicksort leftlist ++ x ++ quicksort rightlist
rightlist :: (Ord a) => [a]
leftlist :: (Ord a) => [a]
但是我的版本在where
行上给了我一个解析器错误。是否可以使用where
代替let
实现快速排序?
答案 0 :(得分:4)
是否有可能使用'where'而不是'let'来实现快速排序?
是。
let letDefines
in expression
通常相当于
expression
where letDefines
所以在你的情况下我们得到
quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) = quicksort smallerOrEqual ++ [x] ++ quicksort larger
where
smallerOrEqual = [a | a <- xs, a <= x]
larger = [a | a <- xs, a > x]
答案 1 :(得分:2)
where
子句定义在函数主体中使用的函数或值。在你的代码中,where
子句将被完全忽略,即使它已经解析,因为你的守卫会立即返回一个值并且不会递归。
quicksort (x:xs)
| head(xs) >=x = head(xs):rightlist
| otherwise = head(xs):leftlist
where quicksort leftlist ++ x ++ quicksort rightlist
这相当于:
quicksort (x:xs) = if head(xs) >= x
then head(xs):rightlight
else head(xs):leftlist
where
子句中没有任何内容发生。如果要在where子句中定义rightlist
和leftlist
,则代码需要不同的格式。如图所示,您的代码在检查前两个元素后结束。 @Zeta很好地解释了如何将let转换为where。