我在浏览Data.Foldable的源代码时遇到了Endo #. f
,并且在单击此链接时遇到了以下问题:
(#.) _f = coerce
现在,首先,我不知道
coerce
和之前提到的Coercible
是什么,但是,这让我更加困惑_f
的含义。我搜索了“变量前的Haskell下划线”和类似内容,仅发现了有关_
模式匹配语法的讨论。 最佳答案
根据Haskell规范,它只是变量的另一个可能名称。但是事实要更长一些,因为大多数Haskell开发人员都是专门为GHC编写代码的,而这就是其中之一。
GHC有很多有用的警告;一种方法是在您编写一个绑定(bind)一个未在函数主体中使用的变量的模式时向您发出警告。它非常方便,并且发现了我的一些错误。但是,它具有链式效应:如果编写仅在一个子句或另一个子句中使用某些变量的函数,则会收到警告。例如,这是列表上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
现在,我两全其美:如果我忘记使用绑定(bind)的变量,则会得到一个很好的警告,并且我仍然可以向读者提供有关当前子句不需要的模式中的孔的含义的信息。 。 (作为一个旁注,如果我错误地使用了以
_
开头的变量,我会报告一条警告,但我认为此刻它不存在!这听起来很愚蠢(“一个函数体”),但我偶尔发现编辑器的Tab补全为我插入了它们,很容易就不会注意到您是否正在快速编码。)关于haskell - 在Haskell中,下划线在变量之前是什么意思?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50705757/