Haskell 帮助函数的好名字是什么?
考虑以下问题:给定一个长度为三个元组(String,Int)的列表,是否有一对元素具有相同的“Int”部分?(例如,Haskell 帮助函数的好名字是什么?,haskell,naming-conventions,Haskell,Naming Conventions,考虑以下问题:给定一个长度为三个元组(String,Int)的列表,是否有一对元素具有相同的“Int”部分?(例如,[(“bob”,5),(“gertrude”,3),(“al”,5)]包含这样一对,但是[(“bob”,5),(“gertrude”,3),(“al”,1)]不包含这样一对。) 这就是我将如何实现这样一个功能: import Data.List (sortBy) import Data.Function (on) hasPair::[(String,Int)]->Bool
[(“bob”,5),(“gertrude”,3),(“al”,5)]
包含这样一对,但是[(“bob”,5),(“gertrude”,3),(“al”,1)]
不包含这样一对。)
这就是我将如何实现这样一个功能:
import Data.List (sortBy)
import Data.Function (on)
hasPair::[(String,Int)]->Bool
hasPair = napkin . sortBy (compare `on` snd)
where napkin [(_, a),(_, b),(_, c)] | a == b = True
| b == c = True
| otherwise = False
我使用模式匹配将名称绑定到元组的“Int”部分,但我想先排序(以便将类似的成员分组),因此我将模式匹配函数放在where
子句中。但这就引出了我的问题:为where
子句中的函数选择名称的好策略是什么?我希望能很快想到这样的名字。在这个例子中,“hasPair”似乎是一个不错的选择,但它已经被采用了!我发现这种模式出现了很多次——辅助函数的自然名称已经被调用它的外部函数使用了。因此,我有时会将这些助手函数称为“op”、“foo”,甚至是“helper”——在这里,我选择了“napkin”来强调它的用途,一次就把它扔掉
那么,亲爱的读者们,你们会怎么称呼“餐巾”?更重要的是,您一般如何处理这个问题?局部范围变量命名的一般规则
,f
,k
,g
用于超简单的本地半匿名事物h
用于(尾部)递归帮助程序()go
,n
,m
,i
用于长度和大小以及其他数值j
获取地图查找和其他字典类型的结果v
- 字符串的
和s
t
和a:as
和x:xs
用于列表y:ys
用于元组字段(a,b,c,)
k
或eq3
这样的东西
对于派生值,尽量少用撇号。我倾向于调用布尔值函数
p
作为谓词<不幸的是,code>pred已经被采用了。在这种情况下,内部函数基本上与外部函数相同,但前提条件不同(需要对列表进行排序),我有时会将相同的名称与素数一起使用,例如hasPairs'
然而,在这种情况下,我更愿意尝试将问题分解为在顶层有用的部分。这通常也使命名它们更容易
hasPair :: [(String, Int)] -> Bool
hasPair = hasDuplicate . map snd
hasDuplicate :: Ord a => [a] -> Bool
hasDuplicate = not . isStrictlySorted . sort
isStrictlySorted :: Ord a => [a] -> Bool
isStrictlySorted xs = and $ zipWith (<) xs (tail xs)
hasPair::[(字符串,Int)]->Bool
hasPair=haspaire。地图snd
hasDuplicate::Ord a=>[a]->Bool
hasdeplicate=不是。是严格分类的。分类
IsStritlySorted::Ord a=>[a]->Bool
IsStritlySorted xs=和$zipWith(我的策略与Don的建议非常接近:
如果有一个明显的名字,使用它
如果是“工作者”或在其他方面与原始功能非常相似,则使用go
根据上下文遵循个人约定,例如,对于折叠的args,遵循步骤
和开始
如果其他方法都失败了,只需使用一个通用名称,如f
我个人避免使用两种技巧。一种是使用原始函数的撇号版本,例如hasPair
的where子句中的hasPair'
。当你指的是另一个时,很容易意外地编写一个;在这种情况下,我更喜欢使用go
。但这并不是一个大问题,只要函数ns有不同的类型。另一种是使用可能包含某些内容的名称,但与函数的实际功能无关。napkin
将属于此类别。当您重新查看此代码时,此命名选择可能会让您感到困惑,因为您将忘记将其命名为napk的原始原因在
(因为餐巾纸有四个角?因为它们很容易折叠?因为它们能清理垃圾?它们在餐馆里被发现?)其他的违例者是像
bob和MyColfunc
这样的东西
如果你给了一个函数一个比
go
或h
更具描述性的名称,那么你应该能够查看它使用的上下文或函数体,并且在这两种情况下都能很好地理解为什么选择这个名称。这就是我的观点#3:个人约定。很多Don的建议适用。如果您在协作情况下使用Haskell,那么请与您的团队协调,并确定常见情况下的某些约定。go
是一种方法:)一个通用指标-使用简短的描述性名称,如果您很难做到恰当的描述性,请尽量简短。顺便说一句,目前编写的napkin
不是很可靠(列表中必须有三个成员),如果你再仔细想想,也许会建议一个更好的名称。@斯蒂芬:是的,我在编写时就意识到了这一点。但是,您是否会说这在总体上是正确的:如果您很难命名函数,那么您的设计可能需要改进?如果是真的,这是一个非常强大的概念…@gcbenison-对于顶级函数,我同意你的格言。复杂的名称是一个信号,表明某些东西还不够完善。在where close中定义的新hasPair不是优先并隐藏外部hasPair吗?在这么短的一段代码中,几乎没有混淆的风险…只是为了让阅读本文的人清楚:这些不是Haskell语言的规则,它们是(非常常见的)约定。k
不是延续的常规名称吗?哦,是的,和p
和q
表示谓词。m
表示一元行为的参数