Suppose I have something along these lines
data Foobar
= Foo with
f: Int -> Int
| Bar with
b: Int
Would it be somehow possible to have a template definition where a Bar
(but not a Foobar
) is a field of a template?
If I try to add this data definition to the basic template for create-daml-app
and then add a field of type Bar
to the User
template I get the following error:
daml/User.daml:16:10: error:
• Expecting one more argument to ‘Bar’
Expected a type, but ‘Bar’ has kind ‘Int -> Foobar’
• In the type ‘Bar’
In the definition of data constructor ‘User’
In the data declaration for ‘User’
Out of sheer curiosity, since the error seemed to point out at the need to add an integer to the type definition, I’ve done it by defining the type of the field to be Bar 42
and the following error comes up
daml/User.daml:16:10: error:
• Expected a type, but ‘Bar 42’ has kind ‘Foobar’
• In the type ‘Bar 42’
In the definition of data constructor ‘User’
In the data declaration for ‘User’
Bar
is not a separate type in Daml, it only exists at the value level. The only type is Foobar
. So you cannot have a field of type Bar
. You can only have a field of type Foobar
. This is different from language like scala where you define separate types that extend the sealed trait/class instead of purely value-level constructors.
Note that this is not true in Daml-LF. The compiler automatically creates a type called Foobar.Bar
here but you cannot access this in Daml. This is documented in How Daml types are translated to Daml-LF — Daml SDK 2.0.0 documentation
I see, thanks. This means that in practice it’s impossible to observe a value of type Foobar
over the Ledger API if any of its cases is not serializable, would that be correct?
Yes, if one case is not serializable the whole variant is not serializable.
1 Like
If you want to emulate that in Daml, you’ll have to make Bar
its own standalone type, and then “wrap” it in FooBar
:
data Bar = Bar (Int -> Int)
data Foo = Foo Int
data FooBar
= FooBar_Bar Bar
| FooBar_Foo Foo
This can get a bit cumbersome and verbose though, so depending on the use-case it may not be worth it.