MoonBit Language Tour MoonBit

Patterns in match expression

In this example, we define a Resource type that describes a file system. The Resource can be a text file, an image, or a folder associated with more files.

The count function traverses the input res recursively and returns the count of Image and TextFile, using a match expression.

Match expressions have first match semantics. They will try to find the first matching pattern sequentially from the first case to the last case and execute the corresponding matched expression. If no pattern matches, the program will abort.

The match expression has an Int return value because all the cases result in the same value type Int.

Patterns can be nested. If you don't care about the data associated with the enum constructor, you can use the any pattern, written as _, instead of introducing a new variable.

enum Resource {
  TextFile(String)
  Image(String)
  Folder(Map[String, Resource])
} derive(Show)

let assets : Resource = Folder(
  {
    "readme.md": TextFile("hello world"),
    "image.jpg": Image("https://someurl1"),
    "folder1": Folder(
      {
        "src1.mbt": TextFile("some code1"),
        "src2.mbt": TextFile("some MoonBit code 2"),
      },
    ),
    "folder2": Folder(
      {
        "src3.mbt": TextFile("some code3"),
        "image2.jpg": Image("https://someurl2"),
      },
    ),
  },
)

fn main {
  println("resource count: \{count(assets)}")
}

fn count(res : Resource) -> Int {
  match res {
    Folder(map) => {
      let mut sum = 0
      for name, res in map {
        sum += count(res)
      }
      sum
    }
    TextFile(_) => 1
    Image(_) => 1
  }
}