| 📦 Turbo MoonBit cc1f595 k33g 15h ago | 1 | ///| |
| 2 | /// A shape that knows its own area. |
| 3 | pub(open) trait Area { |
| 4 | fn area(Self) -> Double |
| 5 | } |
| 6 | |
| 7 | ///| |
| 8 | /// A circle, by its radius. |
| 9 | pub(all) struct Circle { |
| 10 | radius : Double |
| 11 | } derive(Eq, Debug) |
| 12 | |
| 13 | ///| |
| 14 | /// A rectangle, by its two sides. |
| 15 | pub(all) struct Rect { |
| 16 | width : Double |
| 17 | height : Double |
| 18 | } derive(Eq, Debug) |
| 19 | |
| 20 | ///| |
| 21 | pub impl Area for Circle with fn area(self) { |
| 22 | 3.141_592_653_589_793 * self.radius * self.radius |
| 23 | } |
| 24 | |
| 25 | ///| |
| 26 | pub impl Area for Rect with fn area(self) { |
| 27 | self.width * self.height |
| 28 | } |
| 29 | |
| 30 | ///| |
| 31 | pub impl Show for Circle with fn output(self, logger) { |
| 32 | logger.write_string("Circle(r=\{self.radius})") |
| 33 | } |
| 34 | |
| 35 | ///| |
| 36 | pub impl Show for Rect with fn output(self, logger) { |
| 37 | logger.write_string("Rect(\{self.width}×\{self.height})") |
| 38 | } |
| 39 | |
| 40 | ///| |
| 41 | /// Raised when a measurement is asked of nothing at all. |
| 42 | pub suberror NoShapes |
| 43 | |
| 44 | ///| |
| 45 | /// total adds up the areas of every shape given. |
| 46 | /// |
| 47 | /// It is generic over anything that implements `Area`, so one function serves |
| 48 | /// circles, rectangles and whatever else somebody adds later. |
| 49 | pub fn[T : Area] total(shapes : Array[T]) -> Double raise NoShapes { |
| 50 | guard shapes.length() > 0 else { raise NoShapes } |
| 51 | let mut sum = 0.0 |
| 52 | for shape in shapes { |
| 53 | sum = sum + shape.area() |
| 54 | } |
| 55 | sum |
| 56 | } |
| 57 | |
| 58 | ///| |
| 59 | /// largest returns the shape with the greatest area, or None for an empty list. |
| 60 | pub fn[T : Area] largest(shapes : Array[T]) -> T? { |
| 61 | let mut best : T? = None |
| 62 | for shape in shapes { |
| 63 | match best { |
| 64 | None => best = Some(shape) |
| 65 | Some(current) => if shape.area() > current.area() { best = Some(shape) } |
| 66 | } |
| 67 | } |
| 68 | best |
| 69 | } |