haskell - 为什么 GHC Haskell 不支持重载记录参数名称?

标签 haskell overloading record aeson idris

我在说的是无法定义:

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/

相关文章:

haskell - 我们如何知道一个类型类是否是另一个类型类的子类型类?

haskell - 由总和类型值填充的反射下拉菜单

design-patterns - 包含几个单子(monad)的 Haskell 设计

haskell - f, g, h::Kleisli ((->) e) a b <=> f >>> (g &&& h) = (f >>> g) &&& (f >>> h)?

C++基于派生类的重载方法

java - 覆盖 - 参数差异

C++ - 编译器如何决定以引用类型作为参数的重载函数?

android - 代号一在捕获音频期间崩溃

random - AWS DynamoDB - 随机选择记录/项目?

delphi - 如何读取/写入记录类型以通过 udp 发送它们?