另一个“功能上的非详尽模式”

时间:2017-02-12 03:24:35

标签: haskell

Begginer Haskell问题。 实际上我发现了类似的问题Haskell error: "non-exhaustive patterns"

Interactive 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 [][] = []

然而,它取决于出现错误的特定合并情况的顺序。 我真的不知道为什么会这样。提前谢谢。

1 个答案:

答案 0 :(得分:7)

这里有两个不同的问题。

你不可能在GHCi中以这种方式定义List<PointFeature> earthquakes = ParseFeed.parseEarthquake(this,earthquakesURL); for(PointFeature ft : earthquakes){ markers.add(new SimplePointMarker(ft.getLocation(), ft.getProperties())); } map.addMarkers(markers); for(Marker mk1 : markers){ if((float) mk1.getProperty("magnitude") > 5.0) mk1.setColor(red); else{ if((float) mk1.getProperty("magnitude") > 4.0 && (float) mk1.getProperty("magnitude") < 5.0) mk1.setColor(yellow); else mk1.setColor(blue); } } map.addMarkers(markers); } (感谢校正,Alec!)

第一个问题,仅发生在交互式会话中,是您定义三个单独的函数merge,每个函数阴影以前一。有关与您有类似问题的人,请参阅here

要输入单个多行定义,您必须使用merge:{

:}

但是,通常,在GHCi中输入多行定义是相当不愉快的,因此最好将定义存储到普通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的定义并非详尽无遗:两个列表参数都非空的情况不会被处理。请注意:

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

因此,merge的正确定义是:

merge

或者,非交互式:

Prelude> :{
Prelude| merge xs [] = xs
Prelude| merge [] ys = ys
Prelude| merge xxs@(x:xs) yys@(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>