Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell recursive/circular module definitions?

I have two modules which imports each other. Haskell doesn't support recursive modules. So how can i rewrite my data types without needs circular module system.

Here is my Character.hs

module Character where
import ItemSystem

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

an here is 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: I will write my all datatypes into one module :( .

like image 655
Umur Gedik Avatar asked Dec 27 '11 23:12

Umur Gedik


2 Answers

Create a third module for the mutually dependent parts:

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 }

Then import it from both the other modules and optionally re-export the stuff you want available from each:

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

import Internal

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

import Internal

-- non-mutually dependent stuff

If this is in a Cabal package, you can then hide the Internal module from the rest of the world by putting it in the Other-modules section instead of Exported-modules.

For completeness: GHC does support mutually recursive modules, but I would not recommend that for simple cases like this.

like image 179
hammar Avatar answered Nov 08 '22 05:11

hammar


Option 1: As hammar suggested, pull the mutually dependent parts into their own module.

Option 2: Put everything into the same module.

Option 3: If you're using GHC, you can create an hs-boot file for one of your modules and have the other module import it with a {-# SOURCE #-} pragma.

like image 5
redxaxder Avatar answered Nov 08 '22 07:11

redxaxder