2016-08-01 17 views
0

私は自分の足を濡らすために私自身のDiplomacyシミュレータをHaskellで構築する作業をしてきました。私は何のためのためのまともな定義を作ってみたと信じてい種類/種類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)であり、私の注文の定義に関してエラーNot in scope: type constructor or class 'Fleet'を得ています。

これはなぜですか?

私はコンボイへの最初の議論が艦隊であり、3番目の議論が軍隊であることを要求できるように、ユニットまたはオーダーの定義を書くことはできますか?

私はこの問題に対する私のアプローチでちょうど "間違っていない"と思いますか?

私はこれを私の検証関数に近づけるべきでしょうか(私が知っている限り、Haskell経由で有効な注文のみを指定する方法はないので、それは表現力豊かですが表現力がありません)?

私はすでに "DataKinds"を使ってみましたが、エラーポストスクリプトでもエラーメッセージが表示されていましたが、Haskellエラーポストスクリプトではたくさんのことが示唆されています。あまりにもそれに留意する)。

+0

私は用語と混同しています。データ型の使用中にエラーを表示しますが、フリートをtypeclassにする方法を尋ねますか?とにかく、 'Fleet'は型ではないので、エラーが発生しています。これは' Unit'型のコンストラクタです。私はあなたのデザインを少し考え直すべきだと思います。また、 'DataKinds'は間違いなくあなたが望むものではありません。これらは、ここでは適用されない高度な機能です。 – pdexter

+0

ああ、私はそれを言ったことを忘れていた。ありがとうございました。これを修正しました。 –

答えて

4
data Unit = Fleet | Army 

Unitはタイプです。その値はFleetまたはArmyのいずれかです。これらはタイプではありません。

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

これはOKです。

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

これらは値であり、OKではありません。上記の行は、全く意味がない

  | Convoy "hello" Territory 42 Territory Territory 

と非常に似ています。

あなたは、単に

  | Convoy Territory Territory Territory 

を使用する場合がありますが、私はゲームに慣れていないので、私はあなたが実際にそこに必要なものを知りません。

また、タイプキャスティングと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 

今、最後の行はokですにそれらを有効にすることです。これは、より多くの "ラッピング"コンストラクタを使用して注文を作成する必要があるということです。上記

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 ...Unitに変換します、その後、Fleet構築し、最終的にはSupport ...なりにOrderいます。

+0

ちょっとわかりやすくするために投稿を編集しました。それで判断すると、私は検証機能のルートに行くと思う(編集を読む)。また、私はtypeclassesとDataKindsが進歩したことを知らなかった(私はこの言語で何がさらに進んでいるのか分からなかった...私にはPeanoの算術的なものが何であるかを理解しようと、 )は、Succ ... oy veyの観点から定義されています)、私はエラー画面でそれらを見てきました。 –

+1

私は、主な質問は次のようだと思います: 'フリート'と '軍隊'にはどんなフィールドがありますか?上に書いたように、彼らは情報を持っていません。そうであれば、議論が唯一の価値であることをすでに知っていれば、「艦隊」の議論を「コンボイ」に引き渡すことで何が得られるでしょうか? – chi

+0

現在、フィールドはありませんが、変更する可能性があります。ユニットに関連付けられているユニットがあるか、ユニットにそれに関連するテリトリーを持たせたい場合は、特定のテリトリー(基本的にはロケーション、つまり英語チャネルはテリトリーになります)が必要かどうかを判断できません。私は 'コンボイ($ユニットsomeTerritory)someTerritory otherTerritory'または何かのものを書くことができるようにすることを望んでいました(削除するだけでMaybeからJustを削除するか、エラーをスローする –