在Haskell中,变量之前的下划线是什么意思?

sch*_*ine 8 haskell

我正在浏览Data.Foldable的来源,我来到这里Endo #. f,点击此链接后,遇到了:

(#.) _f = coerce
Run Code Online (Sandbox Code Playgroud)

现在,首先,我不知道coerce前面提到的Coercible是什么,然而,它更令我感到困惑_f.我搜索过"变量之前的Haskell下划线"和类似内容,并且只发现了关于_模式匹配语法的讨论.

Dan*_*ner 19

根据Haskell规范,它只是变量的另一个可能的名称.但实际情况要长一些,因为大多数Haskell开发人员专门为GHC编写代码,这是其中一个时代.

GHC有很多有用的警告; 一种是在编写一个绑定未在函数体中使用的变量的模式时发出警告.它非常方便,并且捕获了我的一些错误.但是,它具有连锁效应:如果您编写的函数仅在一个子句或另一个子句中使用某些变量,则会收到警告.例如,以下是foldr对列表的非常自然的定义:

 foldr f z [] = z
 foldr f z (x:xs) = x `f` foldr f z xs
Run Code Online (Sandbox Code Playgroud)

哎呀!我们没有f在第一个条款中使用,我们会收到警告.好的,所以很容易修复:

foldr _ z [] = z
foldr f z (x:xs) = x `f` foldr f z xs
Run Code Online (Sandbox Code Playgroud)

不幸的是,现在我们已经丢失了有关第一个变量在代码中的角色应该是什么的信息.在这种情况下,它foldr是如此熟悉,以至于没有什么大的损失,但是在不熟悉的代码库中,需要大量参数的函数,知道每个"漏洞"忽略哪些数据会很好.所以GHC增加了一个特殊的规则:关于未使用变量的警告不会警告你开头的变量名称_- 类似于_它也没有警告你的模式.所以现在我可以写:

foldr _f z [] = z
foldr  f z (x:xs) = x `f` foldr f z xs
Run Code Online (Sandbox Code Playgroud)

现在我得到两全其美:如果我忘记使用我绑定的变量,我会得到一个很好的警告,我仍然可以向读者提供有关当前子句不需要的模式中孔洞含义的信息.(作为一个方面说明,我喜欢那个报告,如果我一个额外的警告不要错误地使用一个变量开始_,但我不认为它存在的那一刻!这听起来很愚蠢("只是不输入_的功能身体"),但我发现我的编辑器的标签完成偶尔会为我插入它们,如果你快速编码就很容易注意到.)