Haskell 具有相同字段名的数据类型

Haskell 具有相同字段名的数据类型,haskell,Haskell,我在Haskell中编写更大的程序时遇到了问题,其中一个问题是,当我使用相同或匹配的字段名定义数据类型时,会出现不明确的错误 data Board = Board { width :: Int, height :: Int } data Player = Player { strength :: Int, width :: Int, height :: Int } 我对编写小程序很满意,但当我发现这个问题时,我就绝望地跑开了 在其他语言中,我可以做到: board.width = 100

我在Haskell中编写更大的程序时遇到了问题,其中一个问题是,当我使用相同或匹配的字段名定义数据类型时,会出现不明确的错误

data Board  = Board  { width :: Int, height :: Int }
data Player = Player { strength :: Int, width :: Int, height :: Int }
我对编写小程序很满意,但当我发现这个问题时,我就绝望地跑开了

在其他语言中,我可以做到:

board.width  = 100;
board.height = 100;

player.width = 5;
player.height = 2;

我发现我可以用类型名(即boardWith、playerWidth)作为每个字段名的前缀,但这是最佳方法和良好实践吗?我该怎么办?

给字段唯一的前缀是一种有效的方法。这是Haskell中的一个已知问题,有几种方法可以解决这个问题


最复杂的解决方案之一是,它基本上实现了一个新的记录系统(或几个,取决于您如何看待它)——允许您在记录之间共享字段,甚至提供了“子类型”的概念。不过,根据您对Haskell的熟悉程度,它可能并不一定容易使用。当然,你应该检查一下。

是的,你可以这样做,或者你可以将这些模块划分成不同的模块,并通过它限定名称。这里有三个基本选项。(1) 使用特定于类型的名称,例如您的
boardWidth
playerWidth
建议。(2) 将每个数据类型定义放入其各自单独的模块中,以便在导入时,可以按照您的描述对其进行访问(例如,
Board.width
),或(3)创建一个类型类,如
HasWidth
,该类需要一个类型来实现属于该类型类的
width
函数,然后将
Board
Player
中的每一个都作为
HasWidth
类型类的一个实例,并使用适当的实现——在幕后,Haskell将调用generic
width
以获得正确的类型。我知道这可能不是xy问题,但在你的情况下,你不应该在播放器中嵌入一个Board吗?
lens
也是一个很好的解决方案,因为它允许使用
makefields
makeClassy
(我个人喜欢
makeClassy
lots.@mb14乙烯基为其记录字段提供了镜头,因此我不一定将它们视为单独的东西。镜头使使用乙烯基更加容易。我觉得这太过分了。到目前为止,预加或创建模块似乎是最好的方法。@catgocat是否过度使用取决于您的选择。)你到底想干什么