3 ms·
Just for kicks, here's a Dart version: enum ItemStatus { notAvailable, available, inUse } enum FieldState { hidden, readOnly, readWrite } FieldSt
by munificent 3y ago
Just for kicks, here's a Dart version:
enum ItemStatus { notAvailable, available, inUse }
enum FieldState { hidden, readOnly, readWrite }
FieldState decide(bool requiresApproval, bool canUserApprove, ItemStatus itemStatus) =>
switch ((requiresApproval, canUserApprove, itemStatus)) {
(true, true, ItemStatus.notAvailable) => FieldState.hidden,
(false, true, ItemStatus.notAvailable) => FieldState.hidden,
(true, false, ItemStatus.notAvailable) => FieldState.hidden,
(false, false, ItemStatus.notAvailable) => FieldState.hidden,
(true, true, ItemStatus.available ) => FieldState.readWrite,
(false, true, ItemStatus.available ) => FieldState.hidden,
(true, false, ItemStatus.available ) => FieldState.readOnly,
(false, false, ItemStatus.available ) => FieldState.hidden,
(true, true, ItemStatus.inUse ) => FieldState.readOnly,
(false, true, ItemStatus.inUse ) => FieldState.hidden,
(true, false, ItemStatus.inUse ) => FieldState.readOnly,
(false, false, ItemStatus.inUse ) => FieldState.hidden,
};
As with F# and Haskell, the compiler will tell you if you didn't cover one of the combinations. In the case of Dart, we go ahead and make it a full compile-time error, not just a warning.
The cool thing about pattern matching over tuples with compile-time exhaustiveness checking is that you can start simplifying and collapsing rows and the compiler will let you know if you made a mistake.
I believe you can simplify the example here to:
FieldState decide(bool requiresApproval, bool canUserApprove, ItemStatus itemStatus) =>
switch ((requiresApproval, canUserApprove, itemStatus)) {
(_, _, ItemStatus.notAvailable) => FieldState.hidden,
(false, _, ItemStatus.available ) => FieldState.hidden,
(false, _, ItemStatus.inUse ) => FieldState.hidden,
(true, false, ItemStatus.available ) => FieldState.readOnly,
(true, _, ItemStatus.inUse ) => FieldState.readOnly,
(true, true, ItemStatus.available ) => FieldState.readWrite,
};
Doing that simplification is a useful exercise to then determine how to express the rules you're modeling in a succinct way.