Extension methods (which Dart also supports) are orthogonal to the pattern matchinng going on here. If you wanted to define that example function as an extension method, you could:
extension on Shape {
double calculateArea() => switch (this) {
Square(length: var l) => l * l,
Circle(radius: var r) => math.pi * r * r
};
}
example(Shape someShape) {
print(someShape.calculateArea();
}
Extension methods are statically dispatched, so they don't give you any way to write code that's polymorphic over the various subtypes. In order to have code specific to each subtype you need something like virtual methods (which requires you to be able to add methods directly to those classes) or type switches (as in the pattern matching like we have here).
Thanks. I'm just wondering why the example didn't show this extension method. It seems more idiomatic to just call it on the receiver instead of passing a parameter.
It's only more idiomatic if you're coming at this from an object-oriented perspective where anything "dispatchy" should be in receiver position. But once you let go of that notion, it's entirely to just have a function that does a type switch.
I am fine with applying either OO / FP approaches. This example is a sealed class, it is just my opinion that the OO version reads better. And the added benefit of having the function namespaced / bound to the class for IDE support (autocomplete) and documentation.