Skip to content

Backpack: Import standalone modules from indefinite packages in instancing modules fails

Say I have the following modules and signatures in a cabal project

module A where
data SomeUsefulThing = SomeUsefulThing
signature B where
import A
someUsefulFun :: SomeUsefulThing -> ()
module B.Instance where
import A
someUsefulFun :: SomeUsefulThing -> ()
someUsefulFun SomeUsefulThing = ()

Note that in B's signature and instance, someUsefulFun share the same type SomeUsefulThing imported from A.

import A
import B

main = pure (someUsefulFun SomeUsefulThing)
cabal-version: 3.4
name: ex2
version: 0.1.0.0
build-type: Simple

library pa
    build-depends: base
    exposed-modules: A
    signatures: B
    hs-source-dirs: pa

library pb
    build-depends: base, ex2:pa
    exposed-modules: B.Instance
    hs-source-dirs: pb

library
  exposed-modules:     Main
  build-depends:       base, ex2:pa, ex2:pb
  mixins:              ex2:pa requires (B as B.Instance),
  hs-source-dirs:      main

When compiling this project, it fails with

<no location info>: error:
    • Identifier ‘someUsefulFun’ has conflicting definitions in the module
      and its hsig file
      Main module: someUsefulFun ::
                     ex2-0.1.0.0:pa[B=<B>]:A.SomeUsefulThing -> ()
      Hsig file:  someUsefulFun :: A.SomeUsefulThing -> ()
      The two types are different
    • while checking that B.Instance implements signature B in ex2-0.1.0.0:pa[B=B.Instance]

The cause is SomeUsefulThing, in the context of pa is imported from A, but in the context of pb, is imported from ex2:pa[B=<B>]:A.

I think it should be possible to use the shared definition of SomeUsefulThing, since A is a completely standalone module (doesn't depend on any indefinite signatures). Even if it did, it is reasonable to think it should also work.

Is this a fundamental limitation or something we can overcome?

Many thanks.

Edited by Rodrigo Mesquita
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information