lambda内部的模式匹配

时间:2016-07-24 12:09:11

标签: haskell lambda pattern-matching

我正在学习Haskell。这是一个简单的例子,但是我想理解为什么我不能在以下示例中使用lambda函数内的模式匹配的概念(即,为什么filterfold'函数运行但是filterfold&# 39;给出运行时错误):

-- Runs
filterfold' :: (a -> Bool) -> [a] -> [a]
filterfold' p zs = foldr (\y zs -> if (p y) then y:zs else zs) [] zs

-- Runtime error: Non-exhaustive patterns in lambda
filterfold :: (a -> Bool) -> [a] -> [a]
filterfold p (z:zs) = foldr (\y (z:zs) -> if (p y) then y:(z:zs) else (z:zs)) [] (z:zs)

1 个答案:

答案 0 :(得分:5)

你可以使用它但是因为编译器告诉你缺少一个案例(当输入是[]时)

看看你是否说z:zs它会尝试将此模式与输入列表匹配 - 如果你

  • 输入[1,2,3] = 1:[2,3],您获得z=1zs=[2,3]
  • 但是当输入[]时,您无法获得zzs以便z:zs = [](从技术上讲,它们基于list-datatype的不同构造函数)

因此,在运行时,当它看到[]并抛出异常时,它将不知道如何处理这种情况/模式。

如果你仔细观察你的例子,你应该看到你从未真正使用过这些部分(意思是zzs - 你只能再次使用z:zs)所以我不能告诉你如何做得更好

无论如何,你可以使用lambda中的case - 表达式:

... = foldr (\ x zs -> case zs of
                         [] -> ...
                         z:zs -> ...

或者您可以使用LambdaCase扩展名将其缩短一点。