Is there a way to limit the length of a Listy within the type definition?
Assume a contract template definition that looks as follows:
template foo
with
item0: Decimal
item1: Decimal
item2: Decimal
item3: Decimal
item4: Decimal
where
....
I want to refactor this template to use a list of decimals.
template foo
with
items: [Decimal]
where
....
Is there a way to limit the length of items to 5 on a type-level or should one use ensure on the template which would be checked only during runtime?
Your best option here is ensure. There are some techniques to enforce this type of stuff at the type-level that work in Haskell but in DAML you run into various issues in particular around data-dependencies and even in Haskell the complexity rarely pays off.
Is there a reason a tuple wouldn’t work here? Assuming that the list length needs to be exactly 5.
type MyItems = (Decimal, Decimal, Decimal, Decimal, Decimal)
Or a record type?
data MyItems = MyItems
with
item1 : Decimal
item2 : Decimal
...
deriving (Eq, Show)
Record types and tuples both force an exact number of elements not a limit on the number of elements.
Apart from that, they also make it super hard to do anything generically. E.g., for a list incrementing each element by one is a simple map (+1). For a tuple, you have to define that yourself and you have to define it separately for each tuple length.
Apart from that, they also make it super hard to do anything generically. E.g., for a list incrementing each element by one is a simple
map (+1). For a tuple, you have to define that yourself and you have to define it separately for each tuple length.
Good point
Record types and tuples both force an exact number of elements not a limit on the number of elements.
From the example it seems as if the length of the list will always be 5 as the items were previously parameters on a template (which I think is a record type anyway)
From the example it seems as if the length of the list will always be 5 as the items were previously parameters on a template (which I think is a record type anyway)
Assuming this, I would go further and put
data List5 a = List5 { a0: a, a1: a, a2: a, a3: a, a4: a }
deriving (Eq, Show, Ord, Functor, Foldable, Traversable)
which gives you a good number of “list” operations such as @cocreature mentions without having to define them yourself, such as fmap (+1) and for.
I can’t speak to the complications with data-dependencies that @cocreature mentions, though.
@stephen’s definition is perfectly fine wtr to data-dependencies and is indeed a good option if you want a fixed length rather than a limit on the length (which is how I read the question initially). It still has the downside that you have to define separate types for each length of list which can get a bit messy.
The use case I was looking at definitely intended to limit the size, not have a fixed size list. Still very good inputs. thank you very much all!