我正在浏览Data.Foldable的来源,我来到Endo #. f
,点击此链接时遇到了:
(#.) _f = coerce
现在,首先,我不知道coerce
和前面提到的Coercible
是什么,然而,它让我更加感到_f
可能意味着什么。我搜索过“变量之前的Haskell下划线”和类似内容,并且只发现了关于_
模式匹配语法的讨论。
答案 0 :(得分:17)
根据Haskell规范,它只是变量的另一个可能名称。但实际情况要长一些,因为大多数Haskell开发人员专门为GHC编写代码,这是其中之一。
GHC有很多有用的警告;一种是在编写一个绑定未在函数体中使用的变量的模式时发出警告。它非常方便,并且捕获了我的一些错误。但是,它具有连锁效应:如果您编写的函数仅在一个子句或另一个子句中使用某些变量,则会收到警告。例如,以下是列表中foldr
的非常自然的定义:
foldr f z [] = z
foldr f z (x:xs) = x `f` foldr f z xs
糟糕!我们在第一个子句中没有使用f
,我们会收到警告。好的,所以很容易解决:
foldr _ z [] = z
foldr f z (x:xs) = x `f` foldr f z xs
不幸的是,现在我们已经丢失了有关第一个变量在代码中的角色应该是什么的信息。在这种情况下,foldr
是如此熟悉,以至于没有大的损失,但是在不熟悉的代码库中,函数需要大量的参数,知道每个“漏洞”忽略了哪些数据会很好。所以GHC增加了一个特殊的规则:关于未使用变量的警告不会警告你以_
开头的变量名称 - 类似于_
模式,它也没有警告你。所以现在我可以写:
foldr _f z [] = z
foldr f z (x:xs) = x `f` foldr f z xs
现在我得到两全其美:如果我忘记使用我绑定的变量,我会收到一个很好的警告,我仍然可以向读者提供有关我不需要的模式中孔的含义的信息目前的条款。 (作为旁注,如果我做错误地使用以_
开头的变量,我会喜欢另外一个警告,但我认为它现在不存在!听起来很愚蠢(“只是不要在函数体中输入_
”,但我发现我的编辑器的标签完成偶尔会为我插入它们,如果你快速编码就很容易注意到。)
答案 1 :(得分:3)
标记未使用的变量只是一种约定。如您所见,_f
的定义中未使用#.
,因此标有下划线。