Hello,
I am trying to use the optionalToEither but it seems I don’t understand it correctly.
I have the following code, which shows an error on the last line of code:
import DA.Either
data Address = Address
with
apartmentNumber: Optional Int
street: Text
city: Text
country: Text
setup : Script ()
setup = script do
let
apartment = Apartment with number = Some 7
street = "street name"
city = "Tel Aviv"
country = "Israel"
apartmentNumber = optionalToEither "No Apartment" apartment.number
let address = Address with apartmentNumber = fromRight apartment.number apartmentNumber, ..
The error that I am getting is:
c:/dev/daml/Hackathon/daml/Main.daml:31:48: error:
• Couldn't match type ‘Optional Int’ with ‘Int’
arising from a functional dependency between:
constraint ‘DA.Internal.Record.HasField "number" Apartment Int’
arising from a use of ‘getField’
instance ‘DA.Internal.Record.HasField
"number" Apartment (Optional Int)’
at <no location info>
I didn’t use strict Int in any place, so I need help in using it the right way?
Thanks
Let’s check the type of fromRight : b -> Either a b -> b. In your case, you have an Either String Int so b = Int. However, that means apartment.number must be of type Int but it is of type Optional Int and you get the error you are seeing.
I’m not quite sure what you are trying to set the field to so I have a hard time suggesting a fix. Maybe you just want to copy the previous value so apartmentNumber = aparment.number?
Why did you say “you have an `Either String Int”… why is it Int and not Optional Int?
apartment.number is defined as Optional Int
I wrote:
optionalToEither "No Apartment" apartment.number
“No Apartment” is String and “apartment.number” is defined as Optional Int.
So the optionalToEither is based on String and Optional Int.
How can I make the command to to return Either String Optional Int?
optionalToEither has type a -> Optional b -> Either a b. In your case, b = Int because you’re passing apartment.number : Optional Int. I don’t quite understand what you expect to get from an Either String (Optional Int). If apartment.number is None, do you expect to get back a Right None? If so, why do you need an Either at all?
Now I understood why it is Int and not Optional Int - please excuse me as I am still quite new with Daml and I am learning it through the work I need to complete.
The thing is that the project is using optionalToEithrt to validate their types and values… and I am supposed to assign them into data structures that will be saved into contracts.
So, while I cannot change the optionalToEither commands, I do need to assign them into Optional Int, and Optional Text fields.
What do you suggest me to do in this case?
I did try to use Some on top of fromRight, but this does not work as well
You could go the other way around with optionalToEither : Either a b -> Optional b. But at that point, I don’t really understand why you’re converting to an Either at all if you’re just going to turn it back into an Optional afterwards.
Maybe take a step back from the code and explain the underlying problem you are trying to solve?
let
apartment = Apartment with number = Some 7
street = "street name"
city = "Tel Aviv"
country = "Israel"
apartmentNumber = optionalToEither "No Apartment" apartment.number
optAptNum = fromRight 0 apartmentNumber
address = Address with apartmentNumber = optAptNum,..
And this does work, however, I don’t understand why.
Why optAptNum is defined as Optional Int
Basically, it is a quite long story to explain, but I will try to do it shortly.
The first step in the project is simply reading data from an external source (XML files) which another team is validating in DAML - and they are outputting the results in case of errors - such as no apartment number and other data as well.
The next step is to assign only the correct values to the contracts’ data members.
So by the time I am getting the data, I am getting the values that were assigned by “optionalToEither”.
And I need to do the matching between these types to the real contract data members which are defined as Optional Int, Optional Text and etc…
If you look at those definitions you can see that Address does not expect an Optional Int but an Int. So in your example above optAptNum = fromRight 0 apartmentNumber does have type Int not Optional Int and that’s why things typecheck. Note though that there is no point in going via Either here if you are going to throw away the text anyway, you can directly go for optAptNum = fromOptional 0 apartmentNumber (and probably change the variable name given that it’s an Int not an Optional Int).
Opps,
I forgot to change it, and I was sure it was defined as Optional Int. So now it is all clear to me.
Sometimes, after doing so many changes in code in order to “play” and understand things that I forgot to change it back, while thinking I already did it.
Thanks a lot @cocreature