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

fho*_*fho 25 haskell overloading record aeson idris

我所说的是无法定义:

data A = A {name :: String}
data B = B {name :: String}
Run Code Online (Sandbox Code Playgroud)

我知道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
Run Code Online (Sandbox Code Playgroud)

写完这篇文章之后,我不太喜欢它......难道这个类型化不能成为荒谬过程的一部分吗?


当我写一些Aeson JSON解析时,我想到了这个想法.如果只是为每种数据类型派生FromJSON实例都太容易了,我必须手工编写所有内容(目前> 1k行和计数).拥有像name或简单地value在数据记录中的名称并不常见.

http://www.haskell.org/haskellwiki/Performance/Overloading提到函数重载会引入一些运行时开销.但实际上我不明白为什么编译器无法在编译时解析它并在内部给它们不同的名称.

这个来自2012年的SO问题或多或少地说明了历史原因并指出了2006年的邮件主题.最近有什么变化吗?

即使存在一些运行时开销,大多数人也不会介意,因为大多数代码几乎不是性能关键.

是否有一些隐藏的语言扩展实际允许这个?我不确定......但我认为伊德里斯实际上是这样做的?

daf*_*daf 3

使用记录语法

data A { name :: String }
Run Code Online (Sandbox Code Playgroud)

隐式定义一个函数

name :: A -> String
Run Code Online (Sandbox Code Playgroud)

如果同时使用a定义A和,则 的类型定义会发生冲突:B{ name :: String }name

name :: A -> String
name :: B -> String
Run Code Online (Sandbox Code Playgroud)

目前尚不清楚您提出的隐式类型类将如何工作,因为如果我们定义两种类型

data A { name :: String }
data B { name :: Text }
Run Code Online (Sandbox Code Playgroud)

那么我们刚刚将问题转移到冲突的类型类定义上:

class Has'name a where
     name :: a -> String

class Has'name a where
     name :: a -> Text
Run Code Online (Sandbox Code Playgroud)

原则上,这可以通过某种方式解决,但这只是记录的几个棘手的相互冲突的理想属性之一。当 Haskell 被定义时,人们决定最好是拥有简单但有限的支持,而不是尝试设计更雄心勃勃和更复杂的东西。对记录的一些改进已经在不同的时间被讨论过,并且有长期的讨论,例如这个 Haskell Cafe 线程。也许 Haskell Prime 会得到解决。

  • @Evi1M4chine:也许你应该阅读一些关于这个问题的大量现有讨论,然后再提出一些实际上效果不佳的东西,然后要求其他人实现它。 (4认同)