(Sorry for the long question, if I could phrase this shorter I would )
What’s the pattern to use with let’s call them parallel variant types? E.g. suppose I have three data types Fields
, Params
and Results
, and I want to indicate that the XFields
always goes with XParams
and XResults
, and same for the Y
s and Z
s?
data Fields = XFields XF | YFields YF | ZFields ZF
deriving (Eq, Show)
data Params = XParams XP | YParams YP | ZParams ZP
deriving (Eq, Show)
data Results = XResults XR | YResults YR | ZResults ZR
deriving (Eq, Show)
I want to write a function
computeSomething: Fields -> Params -> Results
computeSomething f p = ...
that only makes sense for XFields
and XParams
yielding an XResult
, or Y...
or Z...
Is there a way to express that elegantly? I could write
computeSomething (XFields xf) (XParams xp) = XResult ...
computeSomething (XFields xf) p = error "Message"
computeSomething (YFields yf) (YParams yp) = YResult ...
computeSomething (YFields yf) p = error "Message"
But that doesn’t look aesthetic to me, and I don’t make as many guarantees about the Result
as I want.
Here’s some accompanying daml for how I’d use these types:
template Agreement
with
a: Party
b: Party
operator: Party
fields: Fields
where
signatory a, b, operator
nonconsuming choice DoSomething: ContractId ResultInstance
-- I want to guarantee that the `result` in the `ResultInstance` matches the `fields`
with
params: Params -- I want an error if the params don't match the fields
controller operator
do
create ResultInstance
with
result = computeSomething fields params
..
This comes up frequently in Daml when we want the same workflow for slightly different types of legal agreements.