Haskell为什么使用@(as)

Mad*_*ote 2 haskell pattern-matching

遇到这个例子:

buildEntry ws@(w:_) = (w, length ws)
Run Code Online (Sandbox Code Playgroud)

使用ws@(w:_)代替的好处是什么:

buildEntry' (w:ws) = (w, length (w:ws))
Run Code Online (Sandbox Code Playgroud)

由于我只是一个初学者,因此我认为第二个示例的可读性也更好。

chi*_*chi 5

删除原样并不总是可以提高可读性。比较

foo x@(C a b (D c d) (E e f)) = bar x
Run Code Online (Sandbox Code Playgroud)

foo (C a b (D c d) (E e f)) = bar (C a b (D c d) (E e f))
Run Code Online (Sandbox Code Playgroud)

我认为第一个更具可读性。

此外,可能会有一些性能差异。据我所知,使用x@(C ...)然后x稍后参考将使GHC定义x为指向同一存储单元保持的指针(C ...)。相反,使用(C ...)相同的参数可以分配一个新的“对象”,它是原始对象的副本。

当然,GHC可能会应用某种CSE(通用子表达式消除)来仅保留副本。但是,由于CSE并不总是对性能有好处,因此GHC在使用CSE方面非常保守。

目前,在这种特定情况下,我看不到任何优化方面的问题,因此,GHC毕竟可以使用CSE。不过,我对此不确定。

  • 另一个重要的区别是第二个版本充满了引入错误的可能性。第一个版本说我们将整个x传递到bar中。第二个版本说我们将类似x的东西传递给bar,但是在某些方面可能有所不同。 (2认同)