Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 我可以将数据声明包含到其他数据中吗?_Haskell_Algebraic Data Types - Fatal编程技术网

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
上到处进行模式匹配,以获得有效负载。