【问题标题】:Haskell - How does a pattern match fail in a list comprehension?Haskell - 模式匹配如何在列表理解中失败?
【发布时间】:2018-08-19 22:01:25
【问题描述】:

我正在通过 Miran Lipovaca 的“Learn You a Haskell for Great Good!”学习 Haskell。在第 82 页它说

如果模式匹配失败,列表推导将继续移动到下一个元素,失败的元素不会包含在结果列表中。

例子:

ghci> let xs = [(1,3),(4,3),(2,4),(5,3),(5,6),(3,1)]
ghci> [a+b | (a, b) <- xs]
[4,7,6,8,11,4]

我的问题是模式匹配如何失败? 他这是什么意思?我真的不明白。这可能是因为我的英语不好。我请你举个例子,因为我认为这本书没有给出任何模式匹配失败的例子。

我想过如果列表包含列表理解无法处理的类型,那么它会移动到下一个元素,但如果我以这种方式更改列表:

let xs = [(1,3),(4,3),(2,4),(5,3),True,(5,6)]

然后它甚至无法编译,因为它“无法匹配预期的类型”...

【问题讨论】:

  • 试试[a | (a, 3) &lt;- xs]
  • 非常感谢。 :) 现在我知道是什么意思了!
  • 模式确实是 (a,b) 就像在函数中一样 (\ab -> a+b) 1 2 --vs-- ((a,b) -> a+b) (1,2), (ab) 在你的例子中会失败。您可以使用单个变量 a

标签: haskell functional-programming pattern-matching list-comprehension


【解决方案1】:

以下是列表解析中模式匹配失败的一些案例,在 GHCi 中进行了演示:

Prelude> [ () | True <- [True, False,True] ]
[(),()]
Prelude> [ x | (x, True) <- [(1,True), (2,False), (3,True)] ]
[1,3]
Prelude> [ x+1 | Left x <- [Left 1, Right "Hello", Right "world", Left 2] ]
[2,3]

请注意,有些模式永远不会失败,例如x(x,y)(x,(a,b),z)。这是因为它们匹配只有构造函数的类型,而构造函数必须匹配唯一的构造函数。

一般来说,模式匹配涉及多个分支,例如

case someValue of
   Left x  -> ...
   Right y -> ...

foo Nothing = ...
foo (Just x) = ...

在这些情况下,如果我们忘记处理构造函数,当这种情况发生时,我们会得到一个运行时错误。 (打开警告有助于避免这种情况!)。

在列表推导生成器p &lt;- ... 中,我们只能指定一种模式。但是,有一条特殊规则适用:模式匹配失败不是错误,而是被忽略。

【讨论】:

  • 非常感谢这个例子。我明白了。
【解决方案2】:

不是模式匹配失败的例子(元组模式匹配总是)。这就是一个例子:

Prelude> xs = [Just (1,3), Just (4,3), Nothing, Just (5,3), Nothing]
Prelude> [a+b | Just (a, b) <- xs]
[4,7,8]

这里,Just (a, b) 模式仅匹配元素 Just (1,3)Just (4,3)Just (5,3),但不匹配 Nothings,因此这些位置不会出现在最终列表中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-13
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多