DA.List vs DA.List.Total

I see the difference between DA.List and DA.List.Total functions as the use of Optional, e.g.

tail: [a] → [a]
tail: [a] → Optional [a]

Are there any other differences apart from the use of Optional?

DA.List throws exceptions for some functions when they are not defined, e.g., tail on an empty list. DA.List.Total instead returns an Optional for that as you pointed out. That’s the only difference here.

Thanks @cocreature !

I would also recommend preferring either DA.List.Total or DA.NonEmpty over DA.List in production code. The Daml type system does a fantastic job of helping you avoid bugs if you stick to correct-by-construction datatypes and avoid non-total functions wherever possible (ie. functions that throw exceptions).

For example:

  • If you know there must always be at least one element in the list. This means head : [a] -> a can’t fail, so you can encode that in the “correct-by-construction” NonEmpty datatype and use (.hd) : NonEmpty a -> a instead.
  • Alternatively, using DA.List.Total will guarantee that you correctly handle the “oops, that list was empty after all” case as the code won’t allow you to access the a in Some a unless you also handle the None case.
1 Like