Определения рекурсивного/кругового модуля Haskell? - программирование
Подтвердить что ты не робот

Определения рекурсивного/кругового модуля Haskell?

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

Вот мой Character.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 }

UPDATE: я напишу все типы данных в один модуль:(.

4b9b3361

Ответ 1

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

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 поддерживает взаиморекурсивные модули, но я бы не рекомендовал это для простых случаев, подобных этому.

Ответ 2

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

Вариант 2: Поместите все в тот же модуль.

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