Are interface types allowed as interface choice arguments?

The following doesn’t compile:

interface ILinkedList where
  viewtype LinkedListView

  owner : Party

  choice Find : Optional (ContractId ILinkedList) with
      tgt : ILinkedList
    controller owner this
    do
      undefined

  choice Tail : Optional (ContractId ILinkedList)
    controller owner this
    do
      pure (view this).tail

data LinkedListView = LinkedListView with tail : Optional (ContractId ILinkedList)
  deriving (Eq, Show)

with the error:

  daml/Interface.daml:8:10: error:
  • No instance for (Show ILinkedList)
  arising from the first field of ‘Find’ (type ‘ILinkedList’)
  Possible fix:
  use a standalone 'deriving instance' declaration,
  so you can specify the instance context yourself
  • When deriving the instance for (Show Find)

After adding a Show instance for ILinkedList:

instance Show ILinkedList where
  show = show . view

The compiler complains that Find isn’t serializable.

  error type checking interface Interface.ILinkedList choice Find:
  expected serializable type:
  * reason: choice argument
  * found: Interface:Find
  * problem:
  unserializable data type Interface:Find

Changing tgt to a non-interface type like Int resolves both issues (the need for a Show instance and the non-serializable Find error).

Are interface types allowed in interface choice arguments?

I’m not very familiar with interfaces, but I’d expect you to either have a ContractId ILinkedList or a ILinkedListView as argument. Having the interface itself doesn’t make sense to me.

ContractId ILinkedList works for my purposes (tgt is the contract to find). Thanks.

Edit : self is available in interface choices so passing in the contract id to search for is the right thing to do, rather than trying to compare two ILinkedList values.

On second thought, ContractId ILinkedList doesn’t really make sense as an argument for Find–if you have the contract id already you can just fetch the contract, there’s no need to search for it. So maybe this use-case is not a good fit for interfaces.