Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有两个合并函数asc和desc的Haskell合并排序_Haskell_Mergesort - Fatal编程技术网

带有两个合并函数asc和desc的Haskell合并排序

带有两个合并函数asc和desc的Haskell合并排序,haskell,mergesort,Haskell,Mergesort,我想使用合并排序算法。mergeSort是等待合并函数作为第一个参数的主函数。有人知道我的问题在哪里吗?事先非常感谢 mergeSort xs = merge xs mergeDesc xs = reverse (mergeAsc xs) mergeAsc [] = [] mergeAsc [x] = [x] mergeAsc xs = merge (mergeAsc top) (mergeAsc bottom) where (top, bottom) = splitAt (length xs

我想使用合并排序算法。mergeSort是等待合并函数作为第一个参数的主函数。有人知道我的问题在哪里吗?事先非常感谢

mergeSort xs = merge xs
mergeDesc xs = reverse (mergeAsc xs)
mergeAsc [] = []
mergeAsc [x] = [x]
mergeAsc xs = merge (mergeAsc top) (mergeAsc bottom) where (top, bottom) = splitAt (length xs `div` 2) xs
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys) | x <= y    = x : merge xs (y:ys)
                    | otherwise = y : merge (x:xs) ys

将类型签名添加到函数中,问题就会变得很明显:

mergeAsc, mergeDesc :: Ord a => [a] -> [a]

mergeDesc xs = reverse (mergeAsc xs)
mergeAsc [] = []
mergeAsc [x] = [x]
mergeAsc xs = merge (mergeAsc top) (mergeAsc bottom) where (top, bottom) = splitAt (length xs `div` 2) xs

merge :: Ord a => [a] -> [a] -> [a]
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys) | x <= y    = x : merge xs (y:ys)
                    | otherwise = y : merge (x:xs) ys
或者更简单更喜欢

mergeSort = margeAsc
请注意,mergeDesc并不是很好:您首先按错误的顺序对列表排序,然后将其反转?在Haskell中,您希望您的算法足够灵活,能够自行处理不同的排序之类的内容。所以你会定义

mergeSortBy :: (a->a->Ordering) -> [a] -> [a]
mergeSortBy cmp = mSort
 where 
       mSort [] = []
       mSort [x] = [x]
       mSort xs = merge (mSort top) (mSort bottom)
        where (top, bottom) = splitAt (length xs `quot` 2) xs

       merge [] ys = ys
       merge xs [] = xs
       merge (x:xs) (y:ys) = case x`cmp`y of
          LT  -> x : merge xs (y:ys)
          _   -> y : merge (x:xs) ys
然后,您可以简单地定义mergeSort=mergeSortBy compare和mergeSortDesc=mergeSortBy flip compare

还要观察将merge设置为本地函数如何防止实现中的错误

它说它应该声明为:mergeSort::[a]->[a]->[a]->[a]->[a]->[a]作为接受合并函数作为第一个参数的函数

这很奇怪,它不应该被称为mergeSort,而是sortWithMerge之类的。无论如何,这样做很简单:只需抛出仅在merge子函数中使用的cmp!并将其替换为merge作为参数,而不是在本地定义它

sortWithMerge :: ([a]->[a]->[a]) -> [a] -> [a]
sortWithMerge merger = mSort
 where 
       mSort [] = []
       mSort [x] = [x]
       mSort xs = merger (mSort top) (mSort bottom)
        where (top, bottom) = splitAt (length xs `quot` 2) xs

将类型签名添加到函数中,问题就会变得很明显:

mergeAsc, mergeDesc :: Ord a => [a] -> [a]

mergeDesc xs = reverse (mergeAsc xs)
mergeAsc [] = []
mergeAsc [x] = [x]
mergeAsc xs = merge (mergeAsc top) (mergeAsc bottom) where (top, bottom) = splitAt (length xs `div` 2) xs

merge :: Ord a => [a] -> [a] -> [a]
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys) | x <= y    = x : merge xs (y:ys)
                    | otherwise = y : merge (x:xs) ys
或者更简单更喜欢

mergeSort = margeAsc
请注意,mergeDesc并不是很好:您首先按错误的顺序对列表排序,然后将其反转?在Haskell中,您希望您的算法足够灵活,能够自行处理不同的排序之类的内容。所以你会定义

mergeSortBy :: (a->a->Ordering) -> [a] -> [a]
mergeSortBy cmp = mSort
 where 
       mSort [] = []
       mSort [x] = [x]
       mSort xs = merge (mSort top) (mSort bottom)
        where (top, bottom) = splitAt (length xs `quot` 2) xs

       merge [] ys = ys
       merge xs [] = xs
       merge (x:xs) (y:ys) = case x`cmp`y of
          LT  -> x : merge xs (y:ys)
          _   -> y : merge (x:xs) ys
然后,您可以简单地定义mergeSort=mergeSortBy compare和mergeSortDesc=mergeSortBy flip compare

还要观察将merge设置为本地函数如何防止实现中的错误

它说它应该声明为:mergeSort::[a]->[a]->[a]->[a]->[a]->[a]作为接受合并函数作为第一个参数的函数

这很奇怪,它不应该被称为mergeSort,而是sortWithMerge之类的。无论如何,这样做很简单:只需抛出仅在merge子函数中使用的cmp!并将其替换为merge作为参数,而不是在本地定义它

sortWithMerge :: ([a]->[a]->[a]) -> [a] -> [a]
sortWithMerge merger = mSort
 where 
       mSort [] = []
       mSort [x] = [x]
       mSort xs = merger (mSort top) (mSort bottom)
        where (top, bottom) = splitAt (length xs `quot` 2) xs

非常感谢您,我需要知道的最后一件事是,当我将mergeSort函数的类型签名设置为:mergeSort::[a]->[a]->[a]->[a]->[a]->[a]时,应用程序中出现了类型错误。。。如何解决这个问题?这两个类型声明必须是您和我定义它的方式。到目前为止,谢谢@leftaroundabout:为什么您认为它应该是[a]->[a]->[a]->[a]->[a]->[a]?因为我有一个特定的任务要完成,它说它应该声明为:mergeSort::[a]->[a]->[a]->[a]->[a]->[a]作为接受合并函数作为第一个参数的函数。。。还有两个单独的合并函数,它们对值进行升序和降序排序,如我的解决方案所示,这两个函数应该声明为:Ord a=>[a]->[a]任务说明:编写一个mergeSort合并排序函数,它等待合并函数作为第一个参数。mergeSort::[a]->[a]->[a]->[a]->[a]->[a]写两个额外的合并函数,它们将对值进行升序/降序mergeDesc::Ord a=>[a]->[a]->[a]mergeAsc::Ord a=>[a]->[a]->[a]@baron ok。。。虽然正如我所说,这不应该被称为合并排序。至于mergeAsc和mergeDesc,我会再次将它们作为普通mergeGen::a->a->Ordering->[a]->[a]->[a]->[a]的专业化实现,作为mergeAsc=mergeGen compare和mergeDesc=mergeGen$flip compare。非常感谢,这是我需要知道的最后一件事,当我将mergeSort函数的类型签名设置为:mergeSort::[a]->[a]->[a]->[a]->[a]->[a]时,这是应用程序中的类型错误。。。如何解决这个问题?这两个类型声明必须是您和我定义它的方式。到目前为止,谢谢@leftaroundabout:为什么您认为它应该是[a]->[a]->[a]->[a]->[a]->[a]?因为我有一个特定的任务要完成,它说它应该声明为:mergeSort::[a]->[a]->[a]->[a]->[a]->[a]作为接受合并函数作为第一个参数的函数。。。还有两个单独的合并函数,它们对值进行升序和降序排序,如我的解决方案所示,这两个函数应该声明为:Ord a=>[a]->[a]任务说明:编写一个mergeSort合并排序函数,它等待合并函数作为第一个参数。mergeSort::[a]->[a]->[a]->[a]->[a]->[a]写两个额外的合并函数,它们将对值进行升序/降序mergeDesc::Ord a=>[a]->[a]->[a]mergeAsc::Ord a=>[a]->[a]->[a]@baron ok。。。虽然正如我所说,这不应该被称为合并排序。至于mergeAsc和mergeDesc,我将再次将它们作为通用mergeGen::a->a->Ordering->[a]->[a]->[a]->[a]的专门化来实现 s mergeAsc=mergeGen比较和mergeDesc=mergeGen$flip比较。