Hello, all,
Earlier, i requested on the subject of how to compile the modules
with cyclic dependencies, if the .hi files are removed.
Thanks to Sigbjorn Finne <[EMAIL PROTECTED]> for the guidence.
Also Johannes Waldmann wrote
> sorry, this is a no-answer as well, but: who needs them?
> in the few cases where i had a cyclic dependency, and i wanted to
> avoid it (because hugs wouldn't handle it), i re-thought the
> placement of identifiers and the programm looked generally better
> afterwards. Are there typical cases where cyclic module dependencies
> are the "natural" solution?
By the cyclic module dependencies i mean only such situation when, for
example, the module M imports the item <X> from module N, and N imports
some <Y> from M.
Such mutually recursive modules are as natural as the mutually
recursive functions in the source program: f calls g, g calls f.
And i like ghc because it supports such module systems.
You say, hugs does not allow them. This means, probably, hugs does
not support full Haskell-1.4.
Example.
In my experience, there are too many items related to Polynomial.
It is not good to put them in one module. Too much compilation
expense, especially when you are changing the script now and then
- changed is a small part, and re-compiled is everything. Better to
split it into several modules:
------------------------------------------------------------
module Pol where
import PolAux ( polGCD ...)
...
data Polynomial a i = Pol [Monomial a i] ...
<several data declarations>
instance ... => Num (Polynomial a i) where ...
instance ... => WithGCD (Polynomial a i) where
gcD f g = polGCD...
...
<many other instance declarations for Polynomial>
------------------------------------------------------------
module PolAux where
import Pol ( Polynomial(..) ...)
...
polGCD f g = <large implementation>
------------------------------------------------------------
`Pol' contains many instances which formal implementation parts are
small, they refer to the functions from module PolAux - like polGCD.
PolAux (usually there are many such modules) contains the real script
for implementation.
But PolAux has to say `import Pol ...' because polGCD cannot
compute gcd for polynomials without knowing what is polynomial; and
the latter is explained in `data Polynomial ...'. More over polGCD
uses expressions like f+g :: Polynomial a i, which again need to
import the instance Num (Polynomial ...) from Pol.hs. And so on.
Is here possible a natural solution which does not require recursive
modules?
In my practice, the modules are much more recursive (the question is
whether it is so necessary). So ghc was lead into temptation by the
modules
----------------------------------------------------------------
module DInteger ( module DInt, rootInt )
where
import DInt
import Int_ ( factor )
...
rootInt = ...
< many instances for Integer >
----------------------------------------------------------------
module DInt
where
import DInteger
import Int_ ( factor )
...
< many instances for Int >
----------------------------------------------------------------
module Int_ ( factor ...)
where
import DInteger
...
factor ... = ...
<some real implementation code for the operations with Int,Integer>
----------------------------------------------------------------
Here DInteger imports all the items from DInt and re-exports them.
And DInt imports all DInteger items! Why so? Because
(a) DInteger, DInt are to large to be put together.
(b) DInt, Int_ are hidden: the user has to know only one module
DInteger and to import everything from it.
(c) DInt uses one or two instances for Integer declared in DInteger.
But the language does not alow to import them only. To import
some instances for <D> we have to import the data constructor <D>
- and, automatically, all its instances. Besides, in our case,
<D> = Integer (!). So we have to set `import DInteger'.
Right?
At all this, ghc gets a little surprised and issues many warnings
about `weirdness in declaration...'. But it produces quite a workable
code. Good.
Only why the ghc implementors keep on saying the mutually recursive
modules is a headache?
The bold-naive question arises:
if ghc compiles, - without warning and without asking the order of
compilation, - the mutually recursive functions f, g, why cannot it
do this "similarly" for the modules M, N ?
------------------------------------
Sergey Mechveliani [EMAIL PROTECTED]