将`let`转换为`where`

时间:2014-06-03 15:35:01

标签: haskell quicksort

我正在尝试使用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实现快速排序?

2 个答案:

答案 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子句中定义rightlistleftlist,则代码需要不同的格式。如图所示,您的代码在检查前两个元素后结束。 @Zeta很好地解释了如何将let转换为where。