2017-02-12 50 views
0

Begginer Haskell问题。 其实我发现非常相似的问题Haskell error: "non-exhaustive patterns"另一个'功能非穷举模式'

交互的shell:

Prelude> merge [] [] = [] 
Prelude> merge (x:xs) [] = x:xs 
Prelude> merge [] (y:ys) = y:ys 
Prelude> -- merge (x:xs) (y:ys) 

Prelude> merge [][] 
Exception 
Prelude> merge [0][] 
Exception: <interactive>:3:1-22: Non-exhaustive patterns in function merge 

Prelude> merger [][0] 
OK 

事实上例外也存在于非交互式模式

main = do 
    print (merge [1,2,3] []) 
    print (merge [] [1,2,3]) 
    print (merge [] []) 


merge :: (Ord a) => [a] -> [a] -> [a] 
merge (x:xs) [] = x:xs 
merge [] (y:ys) = y:ys 
merge [][] = [] 

但是这取决于particulas合并的特殊情况下的顺序出现错误。 我不知道为什么会发生这种情况。提前致谢。

回答

6

这里有两个单独的问题。

您不可能在GHCi中以这种方式定义 merge(感谢修正,亚历克!)

的第一个问题,这只是发生在互动环节中,是你定义单独的函数调用merge,每个阴影前一个。对于与您的问题非常相似的人,请参阅here

要进入一个多定义,必须使用:{:}

Prelude> :{ 
Prelude| merge [] [] = [] 
Prelude| merge (x:xs) [] = x:xs 
Prelude| merge [] (y:ys) = y:ys 
Prelude| -- merge (x:xs) (y:ys) 
Prelude| :} 
Prelude> 

然而,在一般情况下,进入多定义为GHCI是相当不愉快,所以你最好存储你定义成一个正常的.hs文件,然后将该文件加载到GHCi中。


的第二个问题,即:在交互式会话和非交互式程序发生,那是你的merge定义并不详尽:的情况下当两个列表参数都是非空不被处理。请注意:

  • 如果任一列表参数为空,merge必须返回另一个列表。
  • 如果两个列表都不为空,merge必须提取最小的头元素(在任一列表中),然后递归合并剩下的元素。

因此,merge正确的定义是:

Prelude> :{ 
Prelude| merge xs [] = xs 
Prelude| merge [] ys = ys 
Prelude| merge [email protected](x:xs) [email protected](y:ys) 
Prelude| | x <= y = x : merge xs yys 
Prelude| | otherwise = y : merge xxs ys 
Prelude| :} 
Prelude> merge [1,3..9] [2,4..10] 
[1,2,3,4,5,6,7,8,9,10] 
Prelude> 

或者非交互:

merge xs [] = xs 
merge [] ys = ys 
merge [email protected](x:xs) [email protected](y:ys) 
    | x <= y = x : merge xs yys 
    | otherwise = y : merge xxs ys 
+0

不幸的是,GHC的最新版本并让用户忽略'let',所以每一行都会覆盖前面的一行 – Alec

+0

@Alec:TIL。谢谢! – pyon

+0

请注意,您不仅纠正了语法错误,还更正了代码。由于没有'merge(x:xs)(y:ys)= ..'case – user2407038