代数数据类型中Haskell(可能)中的类型/种类混淆

代数数据类型中Haskell(可能)中的类型/种类混淆,haskell,types,algebraic-data-types,data-kinds,Haskell,Types,Algebraic Data Types,Data Kinds,我一直在努力在哈斯凯尔建造我自己的模拟器,让我的脚湿了 我相信我已经为订单下了一个像样的定义: data Order = Hold Unit Territory | Move Unit Territory Territory | Support Unit Territory Unit Territory Territory | Convoy Fleet Territory Army Territory Territory de

我一直在努力在哈斯凯尔建造我自己的模拟器,让我的脚湿了

我相信我已经为订单下了一个像样的定义:

data Order = Hold Unit Territory
           | Move Unit Territory Territory
           | Support Unit Territory Unit Territory Territory
           | Convoy Fleet Territory Army Territory Territory
  deriving (Eq, Show)
对于那些不熟悉游戏的人,命令以“扣留舰队伦敦”、“移动舰队伦敦英吉利海峡”、“支援舰队英吉利海峡舰队北大西洋-中大西洋”或“舰队英吉利海峡陆军伦敦布雷斯特”等形式书写

现在,单位定义为
data Unit=Fleet | Army(导出Eq,Show)
,我得到的错误
不在范围内:关于我的订单定义,类型构造函数或类“Fleet”

为什么会这样

我应该如何为部队或命令(或者我应该做一些不同的事情)编写定义,以允许我要求护航的第一个参数是舰队,第三个参数是军队

我对这个问题的态度是否“甚至没有错”

我应该在我的验证函数中处理这个问题吗(因为据我所知,没有办法通过Haskell只指定有效的订单。它很有表现力,但没有那么有表现力)

我已经尝试过使用“DataKinds”,但这对我没有任何帮助(尽管错误postscript建议这样做,但是Haskell错误postscripts建议了很多东西,所以我怀疑我是否需要太多注意它)

单元
是一种类型。其值可以是
舰队
陆军
——这些不是类型

data Order = Hold Unit Territory
           | Move Unit Territory Territory
           | Support Unit Territory Unit Territory Territory
                     ^^^^           ^^^^
这些都是类型——好的

这些都是值——不正常。上面的这条线与

           | Convoy "hello" Territory 42 Territory Territory
这毫无意义

您可能只想使用

           | Convoy Territory Territory Territory
但是我不熟悉这个游戏,所以我不知道你在那里真正需要什么

另外,忘记TypeClass和
DataTypes
扩展——除非您真的需要,否则不要使用高级功能


作为另一种选择,如果您确实计划将字段添加到
舰队
陆军
,则将它们转换为类型

data Fleet = F String Int -- dummy fields, you can put none
data Army = A
data Unit = FleetUnit Fleet | ArmyUnit Army    -- added the types here
data Order = Hold Unit Territory
           | Move Unit Territory Territory
           | Support Unit Territory Unit Territory Territory
           | Convoy Fleet Territory Army Territory Territory
现在最后一行就可以了。这样做的代价是您需要使用更多的“包装”构造函数来构建订单,例如

orderExample1 :: Order
orderExample1 = Convoy (F "test" 33) terr1 A terr2 terr3

orderExample2 :: Order
orderExample2 = Support (FleetUnit (F "test2" 55)) terr1 (ArmyUnit A) terr2 terr3
上面,
F…
构建了一个
车队
,然后
FleetUnit…
将其转换为
单位
,最后
支持…
将其转换为
订单

单元
是一种类型。其值可以是
舰队
陆军
——这些不是类型

data Order = Hold Unit Territory
           | Move Unit Territory Territory
           | Support Unit Territory Unit Territory Territory
                     ^^^^           ^^^^
这些都是类型——好的

这些都是值——不正常。上面的这条线与

           | Convoy "hello" Territory 42 Territory Territory
这毫无意义

您可能只想使用

           | Convoy Territory Territory Territory
但是我不熟悉这个游戏,所以我不知道你在那里真正需要什么

另外,忘记TypeClass和
DataTypes
扩展——除非您真的需要,否则不要使用高级功能


作为另一种选择,如果您确实计划将字段添加到
舰队
陆军
,则将它们转换为类型

data Fleet = F String Int -- dummy fields, you can put none
data Army = A
data Unit = FleetUnit Fleet | ArmyUnit Army    -- added the types here
data Order = Hold Unit Territory
           | Move Unit Territory Territory
           | Support Unit Territory Unit Territory Territory
           | Convoy Fleet Territory Army Territory Territory
现在最后一行就可以了。这样做的代价是您需要使用更多的“包装”构造函数来构建订单,例如

orderExample1 :: Order
orderExample1 = Convoy (F "test" 33) terr1 A terr2 terr3

orderExample2 :: Order
orderExample2 = Support (FleetUnit (F "test2" 55)) terr1 (ArmyUnit A) terr2 terr3

上面,
F…
构建了一个
车队
,然后
FleetUnit…
将其转化为
单位
,最后
支持…
将其转化为
订单

我对这个术语有些困惑。您在使用数据类型时显示了错误,但随后询问如何将Fleet设置为typeclass?不管怎么说,您得到这个错误是因为
Fleet
不是一个类型,它是
Unit
类型的构造函数。我认为你应该重新考虑一下你的设计。而且,
数据类型
绝对不是您想要的。这是一个高级功能,这里不适用。哦,我……有点忘了我说过。谢谢你。现在更新修复了这个问题。我对术语有点困惑。您在使用数据类型时显示了错误,但随后询问如何将Fleet设置为typeclass?不管怎么说,您得到这个错误是因为
Fleet
不是一个类型,它是
Unit
类型的构造函数。我认为你应该重新考虑一下你的设计。而且,
数据类型
绝对不是您想要的。这是一个高级功能,这里不适用。哦,我……有点忘了我说过。谢谢你。现在更新修复了这个问题。我刚刚编辑了我的帖子,以进一步澄清这一点。根据这一点判断,我想我只需要执行验证函数路径(阅读编辑)。此外,我不知道TypeClass和DataTypes是高级的(尽管我甚至不知道这种语言的高级功能是什么……我花了整整几天的时间试图理解整个Peano算术中(+)的定义是如何成功的……oy-vey),我在错误屏幕上到处都看到了它们。我想主要的问题是:
Fleet
Army
有字段吗?如上所述,它们不携带任何信息。如果是这样,那么将
Fleet
参数传递给
convory
会有什么好处呢?如果您已经知道该参数只能具有该值,那么现在,它们没有任何字段,但我可以更改它。我无法决定我是否想要一个给定的区域(基本上是一个位置,所以英吉利海峡就是一个区域)有一个与之相关联的单位,或者我是否想要一个与之相关联的区域。我希望能够做一些事情,比如能够编写
护航(消除$unitsometorritory)sometorritory otherTerritory
之类的东西(如果消除只是从Maybe中删除just或抛出一个错误,请参见编辑。如果你想添加字段,可以使用更多类型来完成你想要的操作。是否有任何方法可以像OOP中那样,导出数据类型?基本上说舰队和陆军都是单位,而不必重建它们?我只是编辑了我的帖子来澄清一点