简体   繁体   English

在Haskell中合并两个排序的列表-这些算法之间的区别是什么

[英]Merge two sorted lists in Haskell- what is the difference between these Algorithms

I try to understand, what's the difference between the second two algorithms. 我尝试了解一下,后两种算法有什么区别。

The first one (merge) works well, but when I try to convert the algorithm to Guarded notation (merge') I get a "Non-exhaustive patterns ..." exception. 第一个(合并)工作良好,但是当我尝试将算法转换为“保护的表示法”(合并')时,出现“非穷举模式...”异常。

But why is the third version (merge'') working? 但是为什么第三个版本(合并”)有效? It is almost the same like merge', there has to be something with the list (x:xs) that I don't understand. 就像合并'几乎一样,列表(x:xs)中肯定有一些我不理解的东西。

   1 -- merges two sortedists                                        
   2 merge xs [] = xs
   3 merge [] ys = ys
   4 merge (x:xs) ys
   5     | x <= head ys = x : (merge xs ys)
   6     | otherwise = head ys : (merge (x:xs) (tail ys))
   7     
   8 -- merges two sorted lists (fails with exception)
   9 merge' z@(x:xs) ys
  10     | ys == [] = z
  11     | z == []  = ys
  12     | x <= head ys = x : (merge' xs ys)
  13     | otherwise = head ys : (merge' (x:xs) (tail ys))
  14     
  15 
  16 -- merges two sorted lists (exept the last element of the first list)
  17 merge'' z@(x:xs) ys
  18     | ys == [] = z
  19     | xs == []  = ys
  20     | x <= head ys = x : (merge'' xs ys)
  21     | otherwise = head ys : (merge'' (x:xs) (tail ys))

In merge' and merge'' you assume the first argument to be of the form x:xs , this excludes the empty list, and is causing the problems. merge' merge''您假设第一个参数的格式为x:xs ,这排除了空列表,并导致了问题。

For example 例如

head z@(x:xs) = x

will produce 1 as expected when calling head([1,2,3]) , but head([]) will throw a Non-exhaustive patterns in function head exception because [] does not match x:xs (the @ is not really important here). 将在调用head([1,2,3])时按预期方式产生1 ,但是head([])Non-exhaustive patterns in function head异常中引发Non-exhaustive patterns in function head因为[]x:xs不匹配( @不是真正的在这里很重要)。

In particular, this means that in merge' the z == [] case can never be matched and also merge'' will throw an exception if you call merge [] [1,2,3] for example. 特别是,这意味着在merge' z == []情况下将永远无法匹配,例如,如果您调用merge [] [1,2,3] ,则merge''也会引发异常。

Also note that in merge'' the case xs == [] is problematic. 还要注意,在merge''xs == []的情况是有问题的。 If, for example, we call merge'' [1] [2] , then this case is matched because [1] is 1:[] . 例如,如果我们称为merge'' [1] [2] ,则此情况是匹配的,因为[1]1:[] Then, just ys , ie, [2] is returned and the x , which is 1 , gets lost. 然后,仅返回ys ,即[2] ,而x1丢失。

The difference between the last two solutions is that merge' has a dead branch z == [] - this condition will never hold, given that z@(x:xs) . 最后两个解决方案之间的区别是merge'具有一个死分支z == [] -鉴于z@(x:xs) ,这种情况将永远不成立。

The version merge'' works by mistake - it will break if you try some other inputs, where at some point z==[] . 版本merge''错误地起作用-如果您尝试其他输入,在某些时候z==[]它将中断。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM