Is it possible to determine controllers of a choice programmatically?

I’m looking for a typeclass that’s the equivalent of HasSignatory for templates, but for choices i.e.

class Choice t c o = > HasController c where
  controller : c -> [Party]

Does something like this exist?

1 Like

Unfortunately that’s not possible right now. I’ve opened an issue to track the request at [FEATURE REQUEST] Expose controllers in Daml · Issue #11362 · digital-asset/daml · GitHub.

Note that the type needs to be slightly different: The controllers can depend on both the template as well as the choice argument.

1 Like

Why is this? Shouldn’t there be a unique template for every choice? i.e. a type dependency c -> t?

Consider

template T
  with
    p : Party
  where
    choice C : ()
      controller p
      do pure ()

Now try defining a function C -> [Party] that gives me back p. It won’t work, C is isomorphic to (). You get no information out of which you could construct a party.

1 Like

I suppose what I’m asking is why Choice isn’t defined as class Choice t c r | c -> t, so then you could write something like getControllers : Choice t c r => c -> [Party] = this.p or something along those lines (assuming this is provided by Choice - which is wrong - but I think you get the idea).

There are two questions here:

  1. Why is there no functional dependency from the choice type to the template type?
  2. Would a functional dependency mean that your suggested type works out?

For 1, the answer is slightly subtle: In Daml-LF different choices can share the argument type (across templates and for the same template). In Daml, this is easily missed since usually the compiler generates a new choice type for you. However there already is an important exception: The Archive type is the same for all templates which would break your functional dependency. With Daml Interfaces you can also define other choices that share the argument type.

For 2, it’s useful to remember what a functional dependency defines: It’s a dependency on the type meaning for c -> t given the choice type you can define the template type. But that’s not what you need in your example. To define the controllers you don’t just need the template type you need the template payload, i.e., the template value. A functional dependency absolutely does not give you that. Let’s ignore Archive and interfaces for a second and assume that we have the functional dependency. Going back to my earlier examples let’s assume I have two contracts T alice and T bob. Given C I would be able to determinate that the corresponding template is T but I have no idea which of the two contracts is relevant.

Ah right, I had assumed that because the compiler typically gives you an error if you have two templates with an identical choice signature that this wasn’t possible. I hadn’t considered those exceptions.

Right, that is true. I was thinking I could lift single controllers to the type-level with some newtype + IsParties shenanigans. But let’s not go there :joy: