2016-08-01 100 views
0

我一直在努力在Haskell中构建我自己的Diplomacy模拟器来让我的脚湿润。类型/种类Haskell(也许)在代数数据类型中的混淆

我相信我已经拿出一个像样的定义的顺序是什么:

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 (deriving Eq, Show),我得到关于我对Order的定义的错误Not in scope: type constructor or class 'Fleet'

这是为什么?

我该如何写单位或订单的定义(或者我应该做一些不同的事情),这使我可以要求Convoy的第一个参数是舰队,第三个参数是军队?

我对这个问题的解决方法是“甚至没有错”吗?

我是否应该在我的验证函数中使用这个函数(因为我没有办法通过Haskell指定有效的订单,据我所知,它具有表现力但不具有表现力)?

我已经尝试使用“DataKinds”,但这并没有帮助我(尽管错误postscript建议这样做,然后再次,Haskell错误postscripts提出了很多事情,所以我怀疑我需要支付太过于注意了)。

+0

我有点糊涂的术语。你在使用数据类型时显示你的错误,但然后问如何让舰队变成一个类型类?无论如何,你会得到这个错误,因为'Fleet'不是一个类型,它是'Unit'类型的构造函数。我认为你应该重新考虑一下你的设计。另外,DataKinds绝对不是你想要的。它们是不适用于此的高级功能。 – pdexter

+0

哦,我......有点忘了我说过。感谢那。现在更新已修复此问题 –

回答

4
data Unit = Fleet | Army 

Unit是一种类型。它的值可以是FleetArmy - 这些不是类型。

data Order = Hold Unit Territory 
      | Move Unit Territory Territory 
      | Support Unit Territory Unit Territory Territory 
        ^^^^   ^^^^ 

这些是类型 - 确定。

  | Convoy Fleet Territory Army Territory Territory 
        ^^^^^   ^^^^ 

这些是值 - 不行。上面的线非常相似

  | Convoy "hello" Territory 42 Territory Territory 

这是没有意义的。

你可能只是想利用

  | Convoy Territory Territory Territory 

,但我不熟悉游戏,所以我不知道你的实际需要存在。

此外,忘记与typeclasses和DataKinds扩展 - 不要使用先进的东西,除非你真的需要它。


作为另一个选项,如果你不打算将字段添加到FleetArmy,是把他们分为不同的类型

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 ...建立一个Fleet,然后FleetUnit ...把它变成一个Unit,最后Support ...原来是为Order

+0

我刚刚编辑我的帖子,以澄清更多一点。由此判断,我认为我只是去验证功能路线(阅读编辑)。此外,我不知道类型类和DataKinds是先进的(因为我甚至不知道用这种语言先进的东西是什么......我花了几整天的时间来试图理解整个Peano算术的事情(+ )是根据Succ ... oy vey定义的),我在错误屏幕上看到它们遍布整个地方。 –

+1

我猜主要问题是:“舰队”和“陆军”有任何领域?如上所述,他们没有携带任何信息。如果这样,如果你已经知道这是论证可能具有的唯一价值,那么将“舰队”论证传给“Convoy”会有什么收获呢? – chi

+0

现在,他们没有任何领域,但我可能会改变这一点。我无法决定我是否想要一个给定的地区(基本上是一个地点,所以英吉利海峡将是一个地区),也许有一个单位与之相关联,或者我希望单位有一个与之相关的地区。我希望能够做一些事情,比如能够写'Convoy(消除$ unit someTerritory)someTerritory other Territory'或类似的东西(其中消除只是从可能中删除Just或抛出错误 –