Haskell определения рекурсивных / циклических модулей? - PullRequest
16 голосов
/ 28 декабря 2011

У меня есть два модуля, которые импортируют друг друга. Haskell не поддерживает рекурсивные модули. Итак, как я могу переписать мои типы данных без необходимости круговой модульной системы.

Вот мой Персонаж.hs

module Character where
import ItemSystem

data Character = Character { name :: String, items :: [Item] }

а вот ItemSystem.hs

module Item where
import Character

data ItemEffect = CharacterEffect (Character -> Character)
                | ItemEffect      (Item -> Item)

data Item = Item { name :: String, weight :: Int, effect :: ItemEffect }

ОБНОВЛЕНИЕ: я запишу все свои типы данных в один модуль :(.

Ответы [ 2 ]

17 голосов
/ 28 декабря 2011

Создайте третий модуль для взаимозависимых частей:

module Internal where

data Character = Character { name :: String, items :: [Item] }

data ItemEffect = CharacterEffect (Character -> Character)
                | ItemEffect      (Item -> Item)

data Item = Item { name :: String, weight :: Int, effect :: ItemEffect }

Затем импортируйте его из обоих других модулей и при необходимости реэкспортируйте материал, который вы хотите получить из каждого:

module Character (Character(..), {- etc -}) where

import Internal

-- non-mutually dependent stuff
module Item (Item(..), ItemEffect(..), {- etc -}) where

import Internal

-- non-mutually dependent stuff

Если это пакет Cabal, вы можете скрыть модуль Internal от остального мира, поместив его в раздел Other-modules вместо Exported-modules.

Для полноты: GHC поддерживает взаимно рекурсивные модули , но я бы не рекомендовал это для простых случаев, подобных этому.

5 голосов
/ 28 декабря 2011

Вариант 1: как предложил Hammar, перетащите взаимозависимые части в их собственный модуль.

Вариант 2: поместите все в один и тот же модуль.GHC, вы можете создать файл hs-boot для одного из ваших модулей и заставить другой модуль импортировать его с {-# SOURCE #-} прагмой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...