How to access functions belonging to an implemented interface from the template's choices?

This code compiles and the test passes; however, this isn’t really what interface methods are for. You should use separate typeclasses and instances instead.

data MIV = MIV {x: Int}

interface MyInterface where
  viewtype MIV
  myMethod: Update (Text, Party)

template MyTemplate with
    p: Party
  where
    signatory p
    interface instance MyInterface for MyTemplate where
      view = MIV 42
      myMethod = pure ("here", p)
    choice MyChoice: (Text, Party)
      controller p
      do
        myMethod $ toInterface this

testIt = script do
  alice <- allocateParty "alice"
  result <- submit alice $ createAndExerciseCmd (MyTemplate alice) MyChoice
  result === ("here", alice)

Why is this the wrong abstraction? Because interface methods are really meant for turning concrete interface choices into partially-abstract implementations that have bits and pieces controlled by the concrete template implementation. That is, they are not accessible from the ledger API, whereas the meaningful use cases for interfaces are all about accessibility from the ledger API. To put it another way, if a method is not used in a concrete interface choice, it is not truly “essential for the interface’s choices”.

The proper tool for Daml-code-internal abstractions is the traditional typeclass. Here is a rewrite of the above using typeclasses:

class EssentialMethods t where
  myMethod: t -> Update (Text, Party)

interface MyInterface where
  viewtype MIV

instance EssentialMethods MyTemplate where
  myMethod mt = pure ("here", mt.p)

template MyTemplate with
    p: Party
  where
    signatory p
    interface instance MyInterface for MyTemplate where
      view = MIV 42
    choice MyChoice: (Text, Party)
      controller p
      do
        myMethod this

Note that now myMethod can be invoked directly on this, illustrating one way in which typeclasses give you better Daml-specific APIs than can be accomplished with interfaces alone.

Typeclasses, defined with the class and instance keywords, are far more flexible; templates and interfaces themselves are built on much more sophisticated usage of typeclasses. Even create and exercise are based on typeclass interaction with templates and interfaces, rather than directly defined as bespoke magic for those features. Here’s some more about understanding their role in the standard library.

3 Likes