Haskell 我可以将数据声明包含到其他数据中吗?
我正在给我的机器人写密码 我有一个解析输入的工作代码Haskell 我可以将数据声明包含到其他数据中吗?,haskell,algebraic-data-types,Haskell,Algebraic Data Types,我正在给我的机器人写密码 我有一个解析输入的工作代码 type Position = (Int,Int) data Entity = Player { pId :: Int, pPos :: Position, pBombStock :: Int, pBombRange :: Int } | Bomb { bOwnerId :: Int, bPos :: Position, bTimeLeft :: Int , bBombRange :: Int} derivin
type Position = (Int,Int)
data Entity = Player { pId :: Int, pPos :: Position, pBombStock :: Int, pBombRange :: Int }
| Bomb { bOwnerId :: Int, bPos :: Position, bTimeLeft :: Int , bBombRange :: Int}
deriving Show
-- The entityType will be:
-- For players: 0.
-- For bombs: 1.
-- The owner will be:
-- For players: id of the player ( 0 or 1).
-- For bombs: id of the bomb's owner.
-- The param1 will be:
-- For players: number of bombs the player can still place.
-- For bombs: number of rounds left until the bomb explodes.
-- The param2 is not useful for the current league, and will always be:
-- For players: explosion range of the player's bombs (= 3).
-- For bombs: explosion range of the bomb (= 3).
mkEnt :: Int -> Int -> Int -> Int -> Int -> Int -> Entity
mkEnt 0 o x y p1 p2 = Player { pId = o, pPos = (x,y), pBombStock = p1, pBombRange = p2}
mkEnt 1 o x y p1 p2 = Bomb { bOwnerId = o, bPos = (x,y), bTimeLeft = p1, bBombRange = p2}
mkEnt _ _ _ _ _ _ = error "invalid entity type"
main :: IO ()
main = do
print $ mkEnt 0 1 0 0 0 3
print $ mkEnt 1 1 0 0 0 3
但是当我试图重构实体时
data Entity = Player | Bomb
deriving Show
data Player = Player { pId :: Int, pPos :: Position, pBombStock :: Int, pBombRange :: Int }
deriving Show
data Bomb = Bomb { bOwnerId :: Int, bPos :: Position, bTimeLeft :: Int , bBombRange :: Int}
deriving Show
代码不会编译,错误:多个“Player”声明。
我是否需要任何语言扩展来完成这项工作,或者它无法(通过设计)完成 同一个模块中有两个构造函数,名为
Player
,与Bomb
中的构造函数相同。您可以给其中一个添加如下前缀以消除构造函数的歧义:
data Entity=EPlayer | EBomb
衍生节目
然而,我不认为您的实体
正在做您希望它做的事情。Entity
上的这两个构造函数不携带数据,并且与数据类型Player
和Bomb
没有关系。如果希望实体
构造函数携带数据,可以将其定义为:
data Entity = EPlayer Player | EBomb Bomb
deriving Show
但是到那时,你已经处于你开始的位置了。通过这种重构,您到底想实现什么?在同一个模块中有两个构造函数,分别名为
Player
,而Bomb
也有同样的构造函数。您可以给其中一个添加如下前缀以消除构造函数的歧义:
data Entity=EPlayer | EBomb
衍生节目
然而,我不认为您的实体
正在做您希望它做的事情。Entity
上的这两个构造函数不携带数据,并且与数据类型Player
和Bomb
没有关系。如果希望实体
构造函数携带数据,可以将其定义为:
data Entity = EPlayer Player | EBomb Bomb
deriving Show
但是到那时,你已经处于你开始的位置了。通过这种重构,您到底想要实现什么?我明白了,我认为
实体
更容易阅读,因为构造函数噪音更小。但这会使实体上的模式匹配比我以前的工作代码更难吗?在这种情况下,我将使用有效载荷。如果您移动到单独的实体
类型,那么您必须在EPlayer
和Player
上到处进行模式匹配,以获得有效载荷。我明白了,我认为实体
将更易于读取,因为构造函数噪音更小。但这会使实体上的模式匹配比我以前的工作代码更难吗?在这种情况下,我将使用工作模式。如果您移动到单独的实体
类型,则必须在EPlayer
和Player
上到处进行模式匹配,以获得有效负载。