Haskell 具有相同字段名的数据类型
我在Haskell中编写更大的程序时遇到了问题,其中一个问题是,当我使用相同或匹配的字段名定义数据类型时,会出现不明确的错误Haskell 具有相同字段名的数据类型,haskell,Haskell,我在Haskell中编写更大的程序时遇到了问题,其中一个问题是,当我使用相同或匹配的字段名定义数据类型时,会出现不明确的错误 data Board = Board { width :: Int, height :: Int } data Player = Player { strength :: Int, width :: Int, height :: Int } 我对编写小程序很满意,但当我发现这个问题时,我就绝望地跑开了 在其他语言中,我可以做到: board.width = 100
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将调用genericwidth
以获得正确的类型。我知道这可能不是xy问题,但在你的情况下,你不应该在播放器中嵌入一个Board吗?lens
也是一个很好的解决方案,因为它允许使用makefields
或makeClassy
(我个人喜欢makeClassy
lots.@mb14乙烯基为其记录字段提供了镜头,因此我不一定将它们视为单独的东西。镜头使使用乙烯基更加容易。我觉得这太过分了。到目前为止,预加或创建模块似乎是最好的方法。@catgocat是否过度使用取决于您的选择。)你到底想干什么