I have a question about the use of ‘Either’ when I need to have the option to ‘toggle’ between different Types in the event that a signatory would want to have the same basic data available for a ‘result’ but may want to restrict some of that data with a Bool (see ‘restricted’ below in the template). Basically, the ‘RestrictedResult’ would just provide less data if it is ‘restricted’.
How would I select either type ‘Result’ vs. ‘RestrictedResult’ as what I am trying isn’t working.
template ApiCall
with
provider: Party
requester: Party
broker: Party
idService: Party
entity: Text
entityId: Text
restricted: Bool
requested: Time
where
signatory broker, requester, idService
observer provider
choice Answer: ContractId EsgResult
with
result : Either Result RestrictedResult
result = if (restricted = False) then do result: Result
else result: RestrictedResult
controller provider
do
asOf <- getTime
-- add result here
create EsgResult with ..
Does this get you closer to your intention?
template ApiCall
with
provider: Party
requester: Party
broker: Party
idService: Party
entity: Text
entityId: Text
restricted: Bool
requested: Time
where
signatory broker, requester, idService
observer provider
choice Answer: ContractId EsgResult
controller provider
do
let result = if restricted
then Right $ RestrictedResult with..
else Left $ Result with..
asOf <- getTime
create EsgResult with ..
1 Like
@Stephen_Herzig
I hope you find the example provided by @WallaceKelly useful.
To add to @WallaceKelly’s response, one error to note in your code, which @WallaceKelly corrected, is that the value of the type Either
must be either Right someValue
or Left someOtherValue
.
The other problem in your code is that, if you’d like to pass the value of the result
variable as an argument to the Answer
choice, then the logic that assigns the value to the result
must be implemented outside of the Answer
choice. In other words the if statement, where you choose the value of the result
variable as either Right $ RestrictedResult with ..
or Left $ Result with ..
cannot be implemented inside the Answer
choice. It must be implemented elsewhere.
Alternatively you can have the logic that assigns the value to the result
inside the Answer
choice, as in @WallaceKelly’s example. But then you cannot pass the value of the result
as an argument to the Answer
choice.
2 Likes
It’s important to note that Either Result RestrictedResult
isn’t “toggling” between Result
and RestrictedResult
–it’s just a regular type like any other type. It doesn’t bypass the requirement that every expression has a single type, which is why
if (restricted = False) then do result: Result else result: RestrictedResult
doesn’t work, the if
-expression can’t have the type Result
and the type RestrictedResult
.
In the standard library, Either
is defined as a variant with two data constructors, Left
and Right
:
data Either a b = Left a | Right b
You can read this as “A value of type Either a b
, is either a Left
holding an a
-value, or a Right
holding a b
-value”. Here both Left
’s and Right
’s have the same type, namely Either a b
.
2 Likes
Thanks, all! Very helpful, and solved the issue.