2016-05-02 10 views
5

はのは、私は次のコードを記述しましょう:ハスケル - 解決する周期的なモジュールの依存関係

ゲームモジュール

module Game where 
import Player 
import Card 
data Game = Game {p1 :: Player, 
        p2 :: Player, 
        isP1sTurn :: Bool 
        turnsLeft :: Int 
       } 

プレーヤモジュール

module Player where 
import Card 
data Player = Player {score :: Int, 
         hand :: [Card], 
         deck :: [Card] 
        } 

とカードモジュール

module Card where 
data Card = Card {name :: String, scoreValue :: Int} 

私はいくつかのタラを書くゲームが順不同になるまで、プレイヤーが自分の手札からカードを引いて、自分のスコアにボーナスを追加するロジックを実装する。

しかし、このコードが完成したら、私が書いたゲームモジュールは退屈です!

私はカードゲームをリファクタリングしたいので、単にスコアを追加するのではなく、カードが任意にゲームを変換します。

だから、私はもちろん、モジュール輸入がサイクルを形成します、次の

module Card where 
import Game 
data Card = Card {name :: String, 
        onPlayFunction :: (Game -> Game)    
        scoreValue :: Int} 

Cardモジュールを変更します。

この問題を解決するにはどうすればよいですか?

トリビアルソリューション:

すべてのファイルを同じモジュールに移動します。これは問題をうまく解決しますが、モジュール性は低下します。後で同じカードモジュールを別のゲームに再利用することはできません。

モジュール維持ソリューション:

Cardに型パラメータを追加します。

module Card where 
data Card a = {name :: String, onPlayFunc :: (a -> a), scoreValue :: Int} 

Playerに別のパラメータを追加します:Gameに1つの最後の修飾を有する

module Player where 
data Player a {score :: Int, hand :: [card a], deck :: [card a]} 

module Game where 
data Game = Game {p1 :: Player Game, 
        p2 :: Player Game, 
       } 

これはモジュール性を維持しますが、自分のデータ型にパラメータを追加する必要があります。データ構造が深く入れ子になっていれば、データに多くのパラメータを追加する必要がありました。この方法を複数のソリューションに使用する必要があった場合は、扱いにくいタイプの修飾子になる可能性があります。

このリファクタを解決するための他の有益な解決法がありますか、またはこれらの唯一の2つのオプションはありますか?

答えて

6

あなたの解決策(タイプパラメータを追加する)は悪くありません。あなたのタイプは、(あなたがそれを必要とする場合は、Card OtherGameを使用することができます)、より一般的になっていますが、追加のパラメータを嫌う場合は、どちらかの可能性:

  • は(単に)あなたの相互再帰的なデータ型を含むモジュールCardGameを書き、これをインポート他のものでモジュール、またはghc
  • 、この最後のソリューションはで型宣言のサブセットとCard.hs-bootファイルの書き込みを必要とbreak the circular dependency

{-# SOURCE #-}プラグマを使用します10。

+3

本当に必要な場合を除き、私はむしろ '{ - #SOURCE# - }'/.hs-bootメカニズムを避けることを強く推奨したいと思います。 – leftaroundabout

+1

@leftroundabout:はい、私は気難しくて不快ですが、(imho)ではない[wiki](https://wiki.haskell.org/Mutually_recursive_modules)で言及されているものよりも何らかの議論があります小規模なプロジェクトにも適していますか? –

関連する問題