[编辑] 这个答案只是我对此事的一些随机想法。我推荐我的另一个答案而不是这个答案,因为对于那个答案,我花了更多时间来查找和参考其他人的工作。
记录语法
在黑暗中试探一下:您提出的“基于布局”的语法看起来很像非记录语法data
声明;这可能会导致解析混淆(?)
--record
data Foo = Foo {i :: Int, s :: String} deriving (Show)
--non-record
data Foo = Foo Int String deriving (Show)
--new-record
data Foo = Foo i :: Int, s :: String deriving (Show)
--record
data LotsaInts = LI {a,b,c,i,j,k :: Int}
--new-record
data LostaInts = LI a,b,c,i,j,k :: Int
在后一种情况下,究竟:: Int
适用于什么?整个数据声明?
使用记录语法的声明(当前)类似于构造和更新语法。对于这些情况,基于布局的语法不会更清晰;你如何解析这些额外的=
迹象?
let f1 = Foo {s = "foo1", i = 1}
let f2 = f1 {s = "foo2"}
let f1 = Foo s = "foo1", i = "foo2"
let f2 = f1 s = "foo2"
你怎么知道f1 s
是记录更新,而不是功能应用程序?
命名空间
如果您想将类定义id
的使用与 Prelude 的混合使用id
怎么办?你如何指定你正在使用哪一个?您能想出比合格导入和/或hiding
关键字更好的方法吗?
import Prelude hiding (id)
data Foo = Foo {a,b,c,i,j,k :: Int, s :: String}
deriving (Show)
id = i
ghci> :l data.hs
ghci> let foo = Foo 1 2 3 4 5 6 "foo"
ghci> id foo
4
ghci> Prelude.id f1
Foo {a = 1, b = 2, c = 3, i = 4, j = 5, k = 6, s = "foo"}
这些不是很好的答案,但它们是我得到的最好的答案。我个人认为记录语法没有那么难看。我确实觉得命名空间/模块的东西还有改进的余地,但我不知道如何让它变得更好。