我在说的是无法定义:
data A = A {name :: String}
data B = B {name :: String}
我知道 GHC 只是将其简化为普通函数,解决此问题的惯用方法是:
data A = A {aName :: String}
data B = B {bName :: String}
class Name a where
name :: a -> String
instance Name A where
name = aName
instance Name B where
name = bName
写完后我不太喜欢它……这种类型分类不能成为脱糖过程的一部分吗?
当我写一些 Aeson JSON 解析时,我想到了。仅仅derive the
FromJSON
instances 就太容易了对于每种数据类型,我都必须手动写出所有内容(目前 > 1k 行并计数)。名称如
name
或者干脆value
在数据记录中并不少见。http://www.haskell.org/haskellwiki/Performance/Overloading提到函数重载会引入一些运行时开销。但我实际上不明白为什么编译器无法在编译时解决这个问题并在内部给它们不同的名称。
This SO question from 2012或多或少地陈述了历史原因并指出了 2006 年的一个邮件线程。最近有什么变化吗?
即使会有一些运行时开销,大多数人也不会介意,因为大多数代码几乎不是性能关键。
是否有一些隐藏的语言扩展实际上允许这样做?我再次不确定......但我认为 idris 实际上是这样做的?
最佳答案
许多,主要是次要原因。一是a better answer提出的问题,仅在第一个参数上重载不足以处理所有有用的情况。
你可以“脱糖”
data A { name :: String }
data B { name :: Text }
进入
class Has'name a b | a -> b where
name :: a -> b
data A { aName :: String }
instance Has'name A String where
name :: aName
data B { bName :: Text }
instance Has'name B Text where
name :: bName
但这需要尚未成为标准的 GHC 扩展(功能依赖项)。它将排除仅使用“名称”来创建记录、更新和模式匹配(查看模式可能会有所帮助),因为在这些情况下,“名称”不仅仅是一个函数。您可能可以使用模板 Haskell 完成一些非常相似的事情。
关于haskell - 为什么 GHC Haskell 不支持重载记录参数名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14422169/