Reputation:
I've got a module like that:
module Foo.Bar (
Bar,
not
) where
data Bar = Some Int | Other Int
not (Some x) = ...
not (Other x) = Foo.Bar.not $ Some x
As you see, I have to write Foo.Bar.not
because not
is defined in Prelude
.
Is there a way to alias Foo.Bar
to e.g. B
so that I can write not (Other x) = B.not $ Some x
in the very file where not
is defined?
Upvotes: 2
Views: 218
Reputation: 105885
Is there a way to alias
Foo.Bar
to e.g.B
[...]?
While I'm not sure whether there is a way to alias a module in itself, you could easily alias not
:
module Foo.Bar (
Bar,
Foo.Bar.not
) where
data Bar = Some Int | Other Int
notBar, not :: Bar -> Bool
notBar (Some x) = ...
notBar (Other x) = notBar (Some x)
-- Use 'notBar' in this module, but export only 'not'.
not = notBar
Given that notBar
and B.not
differ only a single character in length, I think this is more or less a valid solution. Furthermore, it doesn't depend on any compiler quirks.
Alternatively, hide the bindings that use the same name from Prelude
:
module Foo.Bar (
Bar,
not
) where
import Prelude hiding (not)
data Bar = Some Int | Other Int
not :: Bar -> Bool
not (Some x) = ...
not (Other x) = notBar (Some x)
Upvotes: 1
Reputation:
It seems like this isn't possible using anything compliant with the Haskell specification and working in GHC.
Anyway, there are ways a similar result can be achieved:
import Prelude hiding (not)
will help.B
and exporting that module within Foo.Bar
Foo.Bar.not
to notBar
Upvotes: 0
Reputation: 10951
Here is a GHC compatible answer, although its a bit of a clutch:
-- B.hs
module B (
Bar,
B.not
) where
data Bar = Some Int | Other Int
not (Some x) = undefined
not (Other x) = B.not $ Some x
-- Foo.Bar.hs
module Foo.Bar (module Foo.Bar) where
import B as Foo.Bar
When Foo.Bar
is imported, Bar
, not
, Foo.Bar.Bar
and Foo.Bar.not
are provided (the first two are suppresed if Foo.Bar
is imported qualified.)
Upvotes: 0
Reputation: 152867
I think it should be technically possible, if a bit painful, in GHC. For example, I would expect things to work if you produced the following two files (following the documentation on mutual recursion):
-- Foo/Bar.hs-boot
module Foo.Bar where
import Prelude(Either)
not :: Either a a -> a
-- Foo/Bar.hs
module Foo.Bar where
import Prelude (Either(..))
import {-# SOURCE #-} Foo.Bar as B
not (Left x) = x
not (Right x) = B.not (Left x)
However, when I try this, I get a complaint that B.not
is not in scope. I suspect this is a bug in GHC, and have filed a ticket here to see if the devs agree.
Upvotes: 2
Reputation: 10951
This should work
module Foo.Bar (
Bar,
B.not
) where
import qualified Foo.Bar as B (not)
data Bar = Some Int | Other Int
not (Some x) = undefined
not (Other x) = B.not $ Some x
be warned though, that if you are using GHC, you will probably need to do some extra work: https://wiki.haskell.org/Mutually_recursive_modules#GHC
Upvotes: 0