gpt4 book ai didi

haskell - 无论模式是否详尽,为什么恒等函数有时会发生变化?

转载 作者:行者123 更新时间:2023-12-02 16:02:58 25 4
gpt4 key购买 nike

考虑这次 GHCi session :

$ ghci
GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help
Prelude> :set -Wincomplete-patterns -Wincomplete-uni-patterns
Prelude> foo t | (_, _) <- t = "Foo"
Prelude> bar t | (_, _) <- id t = "Foo"
Prelude> baz x | Just _ <- x = "Yes" | Nothing <- x = "No"
Prelude> qux x | Just _ <- id x = "Yes" | Nothing <- id x = "No"

<interactive>:3:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘qux’: Patterns not matched: _
Prelude>

为什么 GHC 认为 qux 不完整?我们对 id x 的了解真的比对 x 的了解更多吗?为什么 bar 不像 qux 一样被认为是不完整的?

或者一个可能更清晰的例子:

foo f x
| Just _ <- f x = "Yes"
| Nothing <- f x = "No"

bar f x = case f x of
Just _ -> "Yes"
Nothing -> "No"

据我所知,它们是完全等价的,但前者会产生警告,而后者不会。

最佳答案

看起来 GHC 并不认为相同的表达式是模式保护中的相同值,除非该表达式是单个绑定(bind):

Prelude> f | Just x <- Just 1 = "foo" | Nothing <- Just 1 = "bar"

<interactive>:5:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘f’: Guards do not cover entire pattern space

这更愚蠢,因为很明显这些模式是详尽无遗的。它甚至不能分支。

我想说这可能是正确的做事方式,即使它很奇怪。它鼓励将表达式绑定(bind)到名称,这有助于确保表达式仅计算一次。不过,这确实是一种迂回的方式。

至于为什么在 bar 中没有收到该错误,这是因为只有一个对的构造函数。您正在匹配 id t 的每个可能的输出,即使它是计算表达式。没有您未匹配的替代构造函数。

关于haskell - 无论模式是否详尽,为什么恒等函数有时会发生变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59128155/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com