编译以下快速排序示例时,如何解决输入“ =”上的“解析错误”?
收藏

将下面的代码放入一个.hs文件中,尝试通过“:t xx.hs”导入,但出现错误。看到其他问题后我怀疑是语法问题。希望有人能帮我解决。

quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) =
  let smallerSorted = quicksort [a | a  xs, a <= x]
       biggerSorted = quicksort [a | a  xs, a > x]
  in smallerSorted ++ [x] ++ biggerSorted

获取错误:
不在范围内:“A”
失败,已加载模块:无。


最佳答案:

let子句中两个声明的缩进应该匹配,如:

quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) =
  let smallerSorted = quicksort [a | a <- xs, a <= x]
      biggerSorted = quicksort [a | a <- xs, a > x]  -- no extra spacing
  in smallerSorted ++ [x] ++ biggerSorted

在最初的问题中,您还忘记在列表理解的生成器表达式部分使用<-运算符:因此您应该编写a <- xs,而不是a xs
但是,正如@RobinZigmond所说,可以在=之前和之后添加空格,只要在第一个非空格字符之前有相同数量的空格,就可以了,例如:
quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) =
  let smallerSorted = quicksort [a | a <- xs, a <= x]
      biggerSorted  = quicksort [a | a <- xs, a > x]  -- extra space before =
  in smallerSorted ++ [x] ++ biggerSorted

注意,可以使用partition :: (a -> Bool) -> [a] -> ([a], [a])将列表分成两个列表,其中第一个子列表包含满足谓词的元素,而第二个子列表包含不满足谓词的元素,例如:
import Data.List(partition)

quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) =
  let (smal, big) = partition (x >) xs
  in quicksort smal ++ x : quicksort big

partition函数通常以这样的方式实现:它只在给定列表上迭代一次,并且只执行一次测试。因此,这通常比使用两个分别过滤给定列表的列表理解更有效(一点)。

公众号