0

私は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)

ゲームに慣れていない人のために、命令は「Hold Fleet London」、「Move Fleet London English Channel」、「Support Fleet English Channel Fleet North Atlantic Ocean Mid Atlantic Ocean」、または「Convoy Fleet English Channel Army」の形式で書かれています。ロンドン・ブレスト」など

さて、 Unit を として定義すると、 Order の定義に関してdata Unit = Fleet | Army (deriving Eq, Show)エラーが発生します。Not in scope: type constructor or class 'Fleet'

どうしてこれなの?

Convoy の最初の引数が Fleet で、3 番目の引数が Army であることを要求できるようにするには、Units または Orders の定義をどのように記述すればよいでしょうか (または別のことを行う必要がありますか)。

この問題に対する私のアプローチは「間違っていない」だけですか?

検証関数でこれにアプローチする必要があります (私の知る限り、Haskell を介して有効な注文のみを指定する方法がないためです。それは表現力豊かですが、それほど表現力豊かではありません)。

私はすでに「DataKinds」を使用してみましたが、それはまったく役に立ちませんでした (エラー ポストスクリプトがそうすることを示唆しているにもかかわらず、Haskell エラー ポストスクリプトは多くのことを示唆しているため、あまり注意を払う必要があるとは思えません)それ)。

4

1 に答える 1

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。本当に必要でない限り、高度なものを使用しないでください。


Fleet別のオプションとして、フィールドをおよびに追加する予定がある場合はArmy、それらをタイプに変換することです

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 ...を構築しFleet、それFleetUnit ...を に変換しUnit、最後Support ...に に変換しOrderます。

于 2016-08-01T08:40:32.327 に答える