Importing templates into new modules

In Main.daml I have

template Asset
  with
    issuer : Party
    owner  : Party
    name   : Text
    dateOfAppraisal : Date
    value : Decimal
  where
    ensure name /= ""
    signatory issuer

but when I try to import that template into a Treasury.daml with

module Treasury where

import Main (Asset)

template TreasurerRole
  with
    treasurer : Party
  where
    signatory treasurer

    controller treasurer can
      CreateAsset : ContractId Asset
        with
          owner  : Party
          name   : Text
          dateOfAppraisal : Date
          value : Decimal
        do
          create Asset with issuer = treasurer, ..

DAML complains on the “Asset” in the final line with:

Message:
daml/Treasury.daml:21:18: error:
Not in scope: data constructor ‘Asset’
Perhaps you want to add ‘Asset’ to the import list in the import of
‘Main’ (daml/Treasury.daml:5:1-19).

But I already imported Asset from Main ?

3 Likes

import Main (Asset) will import the type Asset. What you need here is the value Asset, i.e., the constructor for the type. To import that you can use import Main (Asset(..)) to import the type Asset together with all of its constructors or import Main (Asset(Asset)) to import the type Asset and only the constructor Asset.

In this case the two are equivalent. The difference shows if you have a variant like Either in the standard library. Then import Either(Left) will only import Left but not Right.

There is no easy way to import just the constructor but not the type and I would generally discourage trying to do that. Having the types for the expressions you’re working with in scope means that you can add a type signature at any point which is quite convenient.

5 Likes