Haskell 中的单函数类型类命名 | "er" 对比 "has"
Single-function typeclass naming in Haskell | "er" vs "has"
我发现有时很难想出合理的单函数类型类名称。如果方法名称是一个常规动词(如 get、write、read...),那么很容易做 Gophers 对单一方法接口所做的同样的事情——在后面贴一个 "er"(Getter, 作家, Reader...) 完成了。但!如果函数名是一个名词(名称、颜色...),那么在后面添加一个 "er" 就不再有效了。 Namer 和 Colorer 听起来太奇怪了,因为这些词不再是正确的英语。
一个解决方案是在前面添加一个 "has"。然后人们会得到像 HasName、HasColor 这样的东西,它也适用于动词——例如 HasGet 和 HasWrite。这是一个好方法吗?命名包含名词类事物的单功能类型类的推荐方法是什么?
我建议有任何前缀意味着特定的东西,有任何后缀意味着不同的东西。此外,class prefix/suffix 与成员函数上的 prefix/suffix 相关。这个约定应该明确地写在某处。
例如,
module Lib.Colour.Class
-- The following convention is followed
-- Let class prefixes denote that the member has a certain attribute
-- or has some state internally manipulatable.
-- Has- abstracts record type, accessed with get<ClassRootName>
-- Is- Things that *are* another type, coereced with as<ClassRootName>
-- Can- Things that are manipulatable in some way, via do<ClassRootName>
-- Let class suffixes denote types who primarily act on other types
-- -er A thing that does something to another type
class HasColour a where
getColour :: a -> Colour
class IsColour a where
asColour :: a -> Colour
class CanColour a where
doColour :: Colour -> a -> a
class Colourer a where
colour :: CanColour b => a -> b -> b
我最喜欢这个约定的地方是赋予前缀和后缀不同含义的概念。这种考虑使我写 CanColour
而不是 Colourable
,因为可着色的东西被认为具有变化的内部状态。
关于 "color" 和 "name" 的细节,请注意这些名词也是动词。你可以给人起名字,你可以给头发上色。我不认为向其中任何一个添加 -er 对代码来说都是令人反感的——尤其是根据一致约定的收益来衡量。在我的例子中,我使用动词形式的颜色作为成员函数,所以我只会在 class 约束中使用 "colorer",这对我来说似乎很好。
现在,这个约定最终会在某个时候失效,但在它失效之前,它应该可以帮助用户(您)在使用库时对调用约定做出合理的猜测。它还应该有助于指导您开发新的 classes。
所以这是一个建议。在 Hackage 的包中,我认为没有一个明确的标准来指导你的设计。对这个问题的前提有一些公平的批评(在其评论中找到)。然而,预期的设计 确实 有先例。 diagrams
包,例如,似乎做的事情与你在这里尝试的完全一样。这是一个由一位非常受尊敬的作者编写的构建良好的库。
diagrams
使用前缀:Is- IsName; Has- HasOrigin. It uses suffixes: -ed, Traced; -able, Transformable。好吧,它使用太多,也许?在我看来,使用 HasTrace
而不是 Traced
.
可以获得更多的自我一致性。
所以无论你采用什么标准,既然没有明确的共识如何去做,你至少应该争取名称与概念的自洽性,并在评论中明确说明采用的标准。
我发现有时很难想出合理的单函数类型类名称。如果方法名称是一个常规动词(如 get、write、read...),那么很容易做 Gophers 对单一方法接口所做的同样的事情——在后面贴一个 "er"(Getter, 作家, Reader...) 完成了。但!如果函数名是一个名词(名称、颜色...),那么在后面添加一个 "er" 就不再有效了。 Namer 和 Colorer 听起来太奇怪了,因为这些词不再是正确的英语。
一个解决方案是在前面添加一个 "has"。然后人们会得到像 HasName、HasColor 这样的东西,它也适用于动词——例如 HasGet 和 HasWrite。这是一个好方法吗?命名包含名词类事物的单功能类型类的推荐方法是什么?
我建议有任何前缀意味着特定的东西,有任何后缀意味着不同的东西。此外,class prefix/suffix 与成员函数上的 prefix/suffix 相关。这个约定应该明确地写在某处。
例如,
module Lib.Colour.Class
-- The following convention is followed
-- Let class prefixes denote that the member has a certain attribute
-- or has some state internally manipulatable.
-- Has- abstracts record type, accessed with get<ClassRootName>
-- Is- Things that *are* another type, coereced with as<ClassRootName>
-- Can- Things that are manipulatable in some way, via do<ClassRootName>
-- Let class suffixes denote types who primarily act on other types
-- -er A thing that does something to another type
class HasColour a where
getColour :: a -> Colour
class IsColour a where
asColour :: a -> Colour
class CanColour a where
doColour :: Colour -> a -> a
class Colourer a where
colour :: CanColour b => a -> b -> b
我最喜欢这个约定的地方是赋予前缀和后缀不同含义的概念。这种考虑使我写 CanColour
而不是 Colourable
,因为可着色的东西被认为具有变化的内部状态。
关于 "color" 和 "name" 的细节,请注意这些名词也是动词。你可以给人起名字,你可以给头发上色。我不认为向其中任何一个添加 -er 对代码来说都是令人反感的——尤其是根据一致约定的收益来衡量。在我的例子中,我使用动词形式的颜色作为成员函数,所以我只会在 class 约束中使用 "colorer",这对我来说似乎很好。
现在,这个约定最终会在某个时候失效,但在它失效之前,它应该可以帮助用户(您)在使用库时对调用约定做出合理的猜测。它还应该有助于指导您开发新的 classes。
所以这是一个建议。在 Hackage 的包中,我认为没有一个明确的标准来指导你的设计。对这个问题的前提有一些公平的批评(在其评论中找到)。然而,预期的设计 确实 有先例。 diagrams
包,例如,似乎做的事情与你在这里尝试的完全一样。这是一个由一位非常受尊敬的作者编写的构建良好的库。
diagrams
使用前缀:Is- IsName; Has- HasOrigin. It uses suffixes: -ed, Traced; -able, Transformable。好吧,它使用太多,也许?在我看来,使用 HasTrace
而不是 Traced
.
所以无论你采用什么标准,既然没有明确的共识如何去做,你至少应该争取名称与概念的自洽性,并在评论中明确说明采用的标准。