在Haskell中执行guard子句之前对列表进行排序

时间:2018-10-17 01:58:40

标签: haskell

我创建了一个示例,其中有一个整数列表:

mylist = [4,3,1,6,9]

,我有一个函数可以根据列表的长度是否大于0打印出列表中的最大值。但是,我不想编写一个函数来打印最大值,而是想对列表进行排序先降下然后像这样返回头部:

place :: [Int] -> Int
place numlist
    quicksort numlist --is it possible to sort a list beforehand before running the guard clause??
    | length numlist /= 0 = biggestVal
    where biggestVal = head numlist 

其中的快速排序功能是:

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

换句话说,我正在尝试在执行where子句之前对列表进行快速排序,而不必编写

where biggestVal = head $ quicksort numlist

2 个答案:

答案 0 :(得分:1)

通常通过定义执行繁重工作的辅助函数来完成此操作。通常将其命名为go

place :: [Int] -> Int
place = go . quicksort
  where
  go numlist
    | length numlist /= 0 = biggestVal
    where biggestVal = head numList

请注意,此功能不需要防护:

place :: [Int] -> Int
place = go . quicksort
  where go (x:_) = x
        go _ = undefined  -- you didn't define this, what should you do??

还请注意,要在列表中找到最大值,则无需先对其进行排序。

place [x] = x
place []  = undefined -- again: what should this be?
place xs  = foldr1 max xs

事实上,甚至还有一个名字:

place = maximum

它的多态性超出了您的需要:

maximum :: (Ord a, Foldable t) => t a -> a

答案 1 :(得分:0)

除了亚当给出的答案外,请考虑以下几点:

  1. 假设您正在寻找警卫,以便在head之后对quicksort的呼叫不会失败。尝试以这种方式看待它:您是否还要尝试对空列表进行排序?空列表的最大值将是一个空列表,因此,如果您在前面放置一个警卫并且仅在不为空列表的情况下仅排序-> head。

  2. 在Haskell中检查空列表,最好使用null,因为list可以是无限长的。

  3. 如果您想实现自己的max函数,那么仅以max进行排序就显得过头了,因为比较的次数将超过要求。