I have a couple of templates that share a field name (in this case name)
template DivulgeableAsset
with
owner: Party
name: Text
where
signatory owner
-- choices...
template PrivateAsset
with
owner: Party
name: Text
where
signatory owner
-- choices...
Later, in DAML Script, I would like to retrieve contracts that instantiate these templates and extract their respective names. I do something like the following:
run : Script ()
run = do
owner <- fromSome $ partyFromText "owner"
divulgee <- fromSome $ partyFromText "divulgee"
-- expect the owner to see both the divulgeable...
divulgeableAssets <- query @DivulgeableAsset owner
assertEq ["first"] (map ((name : DivulgeableAsset -> Text) . snd) divulgeableAssets)
-- ... and the private asset
privateAssets <- query @PrivateAsset owner
assertEq ["second"] (map ((name : PrivateAsset -> Text) . snd) privateAssets)
Note that I explicitly hinted the compiler the type of the name function. If I donāt, I get the following error:
Ambiguous occurrence ānameā
It could refer to
either the field ānameā,
imported from āMainā at /some/path/daml/Test.daml:13:1-11
(and originally defined
at /some/path/daml/Main.daml:47:5-8)
or the field ānameā,
imported from āMainā at /some/path/daml/Test.daml:13:1-11
(and originally defined
at /some/path/daml/Main.daml:34:5-8)
Is there a cleaner way to disambiguate between those two functions (or, in general, to extract those fields)?
In general no, HLint does not have enough information to judge whether something is a record field or not. You could probably make something that works as long as the record and the usage of the field are in the same module but I expect the implementation effort to be fairly high
I concur. Itās easy enough to locate constructions like name : DivulgeableAsset -> Text however the syntax alone does not carry enough ācontextā for DLint to classify it as a field selector (as @cocreature says, which would then induce a lot of āspecial caseā implementation effort) so if it were to issue hints, they would be highly speculative and often likely false positives which would be annoying and consequently quickly get disabled. Actually, the sample @stefanobaghino-da provides is somewhat interesting in that he reached for selectors in the first instance over dot-syntax which Iād think might be considered as slightly unusual when programming DAML and probably a consequence of prior Haskell experience. In fact if DAML already had the long desired and highly anticipated NoFieldSelectors feature it wouldnāt have been an option
Iād have to write a program to test this but I expect sections to work here too e.g. map ((.name) . snd) divulgeableAssetsSeenByOwner and wonder if inference succeeds if phrased that way? I guess here is another way to dodge the ambiguity : map (\(_, DivulgeableAsset {name}) -> name) divulgeableAssetsSeenByOwner
Using a section, i.e., (.name) . snd does work but at least to me that is significantly harder to read and understand than \(_, asset) -> asset.name so I would not recommend that option here. Of course there might be other examples where the section is useful.