Created
January 1, 2020 17:08
-
-
Save nodinosaur/817656fdfeb2cb3e7e9ce2e68e26b090 to your computer and use it in GitHub Desktop.
Recoded Sum Types example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Root | |
import 'package:meta/meta.dart'; | |
import 'package:sealed_unions/sealed_unions.dart'; | |
/// ====================================================================== | |
/// Everything above this line is a Doublet & Triplet Sealed Union thing | |
/// ====================================================================== | |
enum UsState { florida } | |
enum CaProvince { ontario } | |
class PostalInfo { | |
String street; | |
StateOrProvince stateOrProvince; | |
PostalInfo({ | |
@required this.street, | |
@required this.stateOrProvince, | |
}) : assert(street != null), | |
assert(stateOrProvince != null); | |
@override | |
String toString() => 'PostalInfo street: $street, stateOrProvince: $stateOrProvince'; | |
} | |
class StateOrProvince extends Union2Impl { | |
StateOrProvince(Union2 union) : super(union); | |
// PRIVATE low-level factory | |
// Used for instantiating individual "subclasses" | |
static final Doublet<UsState, CaProvince> _factory = const Doublet<UsState, CaProvince>(); | |
// PRIVATE constructor which takes in the individual weather states | |
StateOrProvince._(Union2<UsState, CaProvince> union) : super(union); | |
// PUBLIC factories which hide the complexity from outside classes | |
factory StateOrProvince.usState(UsState state) => StateOrProvince._(_factory.first(state)); | |
factory StateOrProvince.caProvince(CaProvince province) => StateOrProvince._(_factory.second(province)); | |
@override | |
String toString() => join( | |
(state) => '$state', | |
(province) => '$province', | |
); | |
} | |
void main() { | |
// Correct | |
final postalInfoUS = PostalInfo( | |
street: 'Some US Street', | |
stateOrProvince: StateOrProvince.usState(UsState.florida), | |
); | |
print(postalInfoUS); | |
// Correct | |
final postalInfoCA = PostalInfo( | |
street: 'Some Canadian Street', | |
stateOrProvince: StateOrProvince.caProvince(CaProvince.ontario), | |
); | |
print(postalInfoCA); | |
sendLetter(postalInfoUS); | |
sendLetter(postalInfoCA); | |
} | |
void sendLetter(PostalInfo postalInfo) { | |
postalInfo.stateOrProvince.join( | |
(usState) { | |
printLetter(postalInfo); | |
shipLetterUSPS(); | |
}, | |
(caProvince) { | |
printLetter(postalInfo); | |
shipLetterCanadaPost(); | |
}, | |
); | |
} | |
void printLetter(PostalInfo postalInfo) { | |
// Imagine this prints a physical letter... | |
print( | |
''' | |
******* | |
${postalInfo.street} | |
${postalInfo.stateOrProvince.toString()} | |
Yours truly, | |
The Chief | |
******* | |
''', | |
); | |
} | |
void shipLetterUSPS() { | |
print('Shipping to United States\n\n'); | |
} | |
void shipLetterCanadaPost() { | |
print('Shipping to Canada\n\n'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment