Hi there! I’d like to use a return-case statement. The top-level function generateResetPeriods
fetches the CalculationPeriod
from the generateResetPeriodDates
, which in turn returns a floatingRateDefinition
.
Current return statement with more code:
generateResetPeriods : (Fetch f) => CalculationPeriodDates -> Optional ResetDates -> f [CalculationPeriod]
generateResetPeriods cpds None = generateCalculationPeriods cpds
generateResetPeriods cpds (Some (checkResetDates cpds -> rds)) = do
-- Roll out calculation periods and unadjusted reset dates
cps <- generateCalculationPeriods cpds
let rpDatesV = map generateResetPeriodDates cps
-- Set reset and fixing dates
let adj = get "resetDatesAdjustments" rds.resetDatesAdjustments
let fixingOffset = get "fixingDates" rds.fixingDates
let resetRelativeTo = fromOptional ResetRelativeToEnumCalculationPeriodStartDate rds.resetRelativeTo
mapA (setResetDates resetRelativeTo fixingOffset adj) $ zip cps rpDatesV -- takes cps and reset periods and returns one list
where
-- multiple resets per period not supported yet
generateResetPeriodDates : CalculationPeriod -> [(Date, Date)]
generateResetPeriodDates cp = [(get "adjustedStartDate" cp.adjustedStartDate, get "adjustedEndDate" cp.adjustedEndDate)]
setResetDates :
(Fetch f)
=> ResetRelativeToEnum
-> RelativeDateOffset --
-> BusinessDayAdjustments --
-> (CalculationPeriod, [(Date, Date)]) --
-> f CalculationPeriod
setResetDates resetRelativeTo fixingOffset adj (cp, rpDates) = do
resetDates <-
case resetRelativeTo of
ResetRelativeToEnumCalculationPeriodStartDate -> mapA (adjustDate adj . fst) rpDates
ResetRelativeToEnumCalculationPeriodEndDate -> mapA (adjustDate adj . snd) rpDates
ros <- mapA generateRateObservation resetDates
return $ cp { floatingRateDefinition = Some FloatingRateDefinition
{ calculatedRate = None
, capRate = []
, floatingRateMultiplier = None
, floorRate = []
, rateObservation = ros
, spread = None
}}
...
Is this the right case statement for a 2-element tuple?:
generateResetPeriods : (Fetch f) => CalculationPeriodDates -> Optional ResetDates -> f [CalculationPeriod]
generateResetPeriods cpds None = generateCalculationPeriods cpds
generateResetPeriods cpds (Some (checkResetDates cpds -> rds)) = do
...
where
generateResetPeriodDates : CalculationPeriod -> [(Date, Date)]
generateResetPeriodDates cp = [(get "adjustedStartDate" cp.adjustedStartDate, get "adjustedEndDate" cp.adjustedEndDate)]
...
return $ case (cp.floatingRateDefinition, cp.otherRateDefinition) of
(Some floating, None) ->
cp { floatingRateDefinition = Some FloatingRateDefinition
{ calculatedRate = None
, capRate = []
, floatingRateMultiplier = None
, floorRate = []
, rateObservation = ros
, spread = None
}}
(None, Some other) ->
cp { otherRateDefinition = Some OtherRateDefinition
{ calculatedRate = None
, capRate = []
, floatingRateMultiplier = None
, floorRate = []
, rateObservation = ros
, spread = None
}}
1 Like
Hi @Chris_Rivers, the case
statement looks fine apart from the fact that you are not handling the case where both are None
and both are Some
. Are you seeing any issues?
Two other comments on your code snippet:
- It looks like you already define the result of
generateResetPeriodDates
in the first line of its definition so I’m not sure what the return
is supposed to belong to.
- Note that
return
in DAML is not the same as the return statement in languages like Java. It is a function of type Applicative f => a -> f a
. What it does depends on the Applicative
instance. For lists, i.e. f = []
, it wraps the argument in a singleton list. For Update
it allows you to lift a pure expression into an Update
action that when executed will return the result of evaluating that expression.
1 Like
Hi @cocreature, although I expect either a Some-None or None-Some case, the compiler complained (gave warning) about not having the cases you mentioned and I got this error too:
Scenario execution failed on commit at Test.Event:116:23:
Aborted: /Applications/DEV/DAML/ex-cdm-swaps copy/daml/Org/Isda/Cdm/EventSpecificationModule/Impl/Contract/Payout/InterestRatePayout/Schedule/ResetDates.daml:(63,16)-(79,54): Non-exhaustive patterns in case
Stack trace:
- patError (Control.Exception.Base:36:1)
- generateResetPeriods (Org.Issa.Srm.EventSpecificationModule.Impl.Contract.Payout.InterestRatePayout.Schedule.ResetDates:63:16)
- generateResetPeriods (Org.Issa.Srm.EventSpecificationModule.Impl.Contract.Payout.InterestRatePayout.Schedule.ResetDates:63:7)
...
However, in the case of Some-Some, how to include both floatingRateDefinition
and otherRateDefinition
within the scope of cp
?
For your first comment, I included additional code above for generateResetPeriodDates
for background. The code works fine in test cases with a single return statement, but not so when using the return
case
.
1 Like
Something like this
case (cp.floatingRangeDefinition, cp.otherRateDefinition) of
(Some floating, Some other) -> …
Then in …
both floating
and other
are in scope.
As for your error, I’m sadly still unable to see what is going wrong even with the additional context.
Do you get a compile-time error or a runtime error? Can you share the error message? It would also be super helpful if you have a standalone example to reproduce the error.
1 Like
For the Some-Some
, I haven’t figured out the write syntax for include both records in cp
:
(Some floating, Some other) ->
cp { floatingRateDefinition = Some FloatingRateDefinition
{ calculatedRate = None
, capRate = []
, floatingRateMultiplier = None
, floorRate = []
, rateObservation = ros
, spread = None
}
otherRateDefinition = Some OtherRateDefinition
{ calculatedRate = None
, capRate = []
, floatingRateMultiplier = None
, floorRate = []
, rateObservation = ros
, spread = None
}}
1 Like
You either need to use with
-syntax or a comma:
1.
cp with
floatingRateDefinition = Some …
otherRateDefinition = Some …
-
cp { floatingRateDefinition = Some …,
otherRateDefinition = Some …
}
Note that if you want to do the same thing for one of them independent of whether the other is Some
you are probably better off doing two independent pattern matches.
1 Like
My runtime error:
Scenario execution failed on commit at Test.Event:116:23:
Aborted: /Applications/DEV/DAML/ex-cdm-swaps copy/daml/Org/Issa/Srm/EventSpecificationModule/Impl/Contract/Payout/InterestRatePayout/Schedule/ResetDates.daml:(63,16)-(79,54): Non-exhaustive patterns in case
Stack trace:
- patError (Control.Exception.Base:36:1)
- generateResetPeriods (Org.Isda.Cdm.EventSpecificationModule.Impl.Contract.Payout.InterestRatePayout.Schedule.ResetDates:63:16)
- generateResetPeriods (Org.Isda.Cdm.EventSpecificationModule.Impl.Contract.Payout.InterestRatePayout.Schedule.ResetDates:63:7)
- $$c$u003e$u003e$u003d (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:49:34)
- $$c$u003e$u003e$u003d (Org.Isda.cdm.EventSpecificationModule.Types.ReferenceData.Fetch:48:23)
- $$c$u003e$u003e$u003d (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:48:23)
- $$cfmap (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:37:47)
- $$cfmap (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:37:24)
- $$c$u003c$u002a$u003e (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:42:47)
- $$c$u003c$u002a$u003e (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:42:23)
- $$c$u003e$u003e$u003d (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:48:23)
- $$c$u003e$u003e$u003d (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:48:46)
- $$c$u003e$u003e$u003d (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:48:23)
- $$c$u003e$u003e$u003d (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:48:46)
- $$c$u003e$u003e$u003d (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:48:23)
- $$cfmap (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:37:47)
- $$cfmap (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:37:24)
- $$c$u003c$u002a$u003e (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:42:47)
- $$c$u003c$u002a$u003e (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:42:23)
- $$cfmap (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:37:47)
- $$cfmap (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:37:24)
- $$c$u003e$u003e$u003d (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:48:46)
- $$c$u003e$u003e$u003d (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:48:23)
- $$cfmap (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:37:47)
- $$cfmap (Org.Isda.Cdm.EventSpecificationModule.Types.ReferenceData.Fetch:37:24)
- buildDerivedEvents (Org.Isda.Cdm.EventSpecificationModule.EventBuilder.Derived:37:41)
- buildDerivedEvents (Org.Isda.Cdm.EventSpecificationModule.EventBuilder.Derived:37:1)
- flip (DA.Internal.Prelude:369:1)
- $$cfmap (DA.Internal.LF:129:33)
- $$cfmap (DA.Internal.LF:129:22)
Ledger time: 2018-09-24T00:00:00Z
Partial transaction:
Failed exercise (DA.Internal.Prelude:365:26):
exercise Trigger on #13:0 (Main.Workflow.DeriveEvents:DeriveEventsWorkflow)
with
ciCid = #5:2;
fromDate = some 2019-03-01T;
toDate = some 2019-03-26T;
refData =
(Main.ReferenceData:RefData with
holidayCalendarCids = [#10:0]; observationCids = [#11:0]; novelCids = [#12:0])
Sub-transactions:
#1
└─> fetch #5:2 (Main.Market.Contract:ContractInstance)
#2
└─> fetch #10:0 (Main.ReferenceData:HolidayCalendarInstance)
#3
└─> fetch #11:0 (Main.ReferenceData:ObservationInstance)
#4
└─> fetch #12:0 (Main.ReferenceData:NovelInstance)
patError
sounds like you forgot a case but hit it in your scenario. I would recommend to add even the cases that you think you might not hit and call something like error "unexpected case 1"
, error "unexpected case 2"
.
1 Like
Ok thanks. I’ll reply back either with a solution or standalone example.
1 Like