Haskell 中的字段值和本地范围之间的命名冲突
Naming conflict between field values and local scope in Haskell
这是一个编码风格问题,而不是技术问题。
我经常遇到一个问题,我使用 haskell 的(不太理想的)记录语法(或镜头,问题最终相同)来创建 data
类型。我最终得到了以我的字段命名的字段访问器函数。作为一个认真的程序员,我尽量让我的记录字段名称有意义。
稍后我需要从我的类型中获取一个字段并将其值保存在局部变量中。这通常在 do
块中的 StateMonad 中完成。问题是我怎么称呼局部变量。最明显的名称已被用作字段访问器。我发现我自己使用缩写,这往往会降低我的代码的可读性。
是否有解决此问题的 Haskell 编码约定?
例子
data Qaax = Qaax {
foo :: SomeFoo
, bar :: SomeBar
, ...
}
baz :: (MonadState Qaax m) => (...) -> m ()
baz (...) = do
f <- gets foo -- I'd really like to use something more descriptive then
-- `f` but `foo` is already taken.
...
return ()
NamedFieldPuns
扩展可以帮助解决这个问题。当对记录进行模式匹配时,它会绑定一个与记录字段同名的变量:
{-# LANGUAGE NamedFieldPuns #-}
baz :: (MonadState Qaax m) => m ()
baz = do
Qaax {foo} <- get
return ()
一个可能的问题是 do
块的其余部分隐藏了访问器。
添加 ' 作为后缀是形成不同但相关的名称的既定惯例。一个关键的例子是 foldl
和 foldl'
.
在像 foldl'
这样的导出名称中,通常最好为 ' 对您的图书馆的意义提出一个一致的主题(通常是 "stricter version of",如 foldl'
).但是在本地名称中,您可以更自由地使用它 "another closely related thing I would like to have the same name as".
缺点是它非常不同,因此会影响可读性;特别是如果您需要共同参考这两个版本。当您发现自己需要 foo'''
时,您可能应该考虑一个不同的命名方案!
这是一个编码风格问题,而不是技术问题。
我经常遇到一个问题,我使用 haskell 的(不太理想的)记录语法(或镜头,问题最终相同)来创建 data
类型。我最终得到了以我的字段命名的字段访问器函数。作为一个认真的程序员,我尽量让我的记录字段名称有意义。
稍后我需要从我的类型中获取一个字段并将其值保存在局部变量中。这通常在 do
块中的 StateMonad 中完成。问题是我怎么称呼局部变量。最明显的名称已被用作字段访问器。我发现我自己使用缩写,这往往会降低我的代码的可读性。
是否有解决此问题的 Haskell 编码约定?
例子
data Qaax = Qaax {
foo :: SomeFoo
, bar :: SomeBar
, ...
}
baz :: (MonadState Qaax m) => (...) -> m ()
baz (...) = do
f <- gets foo -- I'd really like to use something more descriptive then
-- `f` but `foo` is already taken.
...
return ()
NamedFieldPuns
扩展可以帮助解决这个问题。当对记录进行模式匹配时,它会绑定一个与记录字段同名的变量:
{-# LANGUAGE NamedFieldPuns #-}
baz :: (MonadState Qaax m) => m ()
baz = do
Qaax {foo} <- get
return ()
一个可能的问题是 do
块的其余部分隐藏了访问器。
添加 ' 作为后缀是形成不同但相关的名称的既定惯例。一个关键的例子是 foldl
和 foldl'
.
在像 foldl'
这样的导出名称中,通常最好为 ' 对您的图书馆的意义提出一个一致的主题(通常是 "stricter version of",如 foldl'
).但是在本地名称中,您可以更自由地使用它 "another closely related thing I would like to have the same name as".
缺点是它非常不同,因此会影响可读性;特别是如果您需要共同参考这两个版本。当您发现自己需要 foo'''
时,您可能应该考虑一个不同的命名方案!