Let’s say I am building a fruit stall selling three types of fruits (apple, orange, and banana) and each kind of fruit has a Validate choice in place to validate an incoming UnknownFruit (which is specified by the user as one of the three types of fruits, but not necessarily the true fruit type):
newtype Colour = Colour Text deriving (Eq, Show)
data FruitType = Apple | Orange | Banana
data UnknownFruit = UnknownFruit
with
colour : Colour
bestGuessFruitType : FruitType -- This is just a best guess, not necessarily the actual fruit type
template Apple
with
colour : Colour
where
signatory ..
nonconsuming choice Validate : Validation Text Colour
with
unknownFruit : UnknownFruit
do
-- Check if the colour is red
template Orange
with
colour : Colour
where
signatory ..
nonconsuming choice Validate : Validation Text Colour
with
unknownFruit : UnknownFruit
do
-- Check if the colour is orange
template Banana
with
colour : Colour
where
signatory ..
nonconsuming choice Validate : Validation Text Colour
with
unknownFruit : UnknownFruit
do
-- Check if the colour is yellow
My question is, given an UnknownFruit, assuming I want to use bestGuessFruitType to locate the template type I want to call, how can I use exerciseByKey to dynamically determine at runtime which Validate choice to exercise?
Thank you so much @bernhard! Good catch about the name clash I was typing it on the text field without IDE support so apologies about that.
Yeah your answer absolutely makes sense I don’t know why I didn’t think of that before. I do have one more follow up question though:
Let’s say this fruit stall solution is fronted by a REST API and all the Daml ledger interaction happen using the RxJava binding DamlLedgerClient class. How can we ‘call’ this validateFruit function on the Java application?
The Ledger API doesn’t allow you to call arbitrary functions, you can only exercise choices. If you’re in control of the Daml code, that’s not as much of a constraint as it may at first appear: you can create a stateless contract that just exposes that one choice. Something like:
template FruitValidator
with s : Party
where
signatory s
choice ValidateFruit : Validation Text Color
with
unknown_fruit : UnknownFruit
controller s
do validateFruit unknown_fruit
which you would call with “create and exercise”.
Or, if you call it often enough that the churn on that contract would matter, you can, say, create one per user and keep it around for further requests. (I.e. by making the choice nonconsuming.)