{"id":281,"date":"2022-05-30T00:17:26","date_gmt":"2022-05-30T00:17:26","guid":{"rendered":"https:\/\/www.kindsonthegenius.com\/scala\/?p=281"},"modified":"2022-05-30T00:17:26","modified_gmt":"2022-05-30T00:17:26","slug":"scala-pattern-matching","status":"publish","type":"post","link":"https:\/\/www.kindsonthegenius.com\/scala\/scala-pattern-matching\/","title":{"rendered":"Scala &#8211; Pattern Matching"},"content":{"rendered":"<p>Pattern matching allows you to check a value against a given pattern. It is similar to <a href=\"https:\/\/www.kindsonthegenius.com\/java\/\" target=\"_blank\" rel=\"noopener\">Java<\/a> and <a href=\"https:\/\/www.kindsonthegenius.com\/cplusplus\/\" target=\"_blank\" rel=\"noopener\">C++<\/a> switch statement, but it&#8217;s more powerful.<\/p>\n<p>The syntax for Scala pattern matching is given below:<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008800; font-weight: bold;\">val<\/span> scores <span style=\"color: #008800; font-weight: bold;\">=<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Seq<\/span><span style=\"color: #333333;\">(<\/span><span style=\"color: #0000dd; font-weight: bold;\">30<\/span><span style=\"color: #333333;\">,<\/span> <span style=\"color: #0000dd; font-weight: bold;\">50<\/span><span style=\"color: #333333;\">,<\/span> <span style=\"color: #0000dd; font-weight: bold;\">60<\/span><span style=\"color: #333333;\">,<\/span> <span style=\"color: #0000dd; font-weight: bold;\">90<\/span><span style=\"color: #333333;\">)<\/span>\r\n<span style=\"color: #008800; font-weight: bold;\">val<\/span> score <span style=\"color: #008800; font-weight: bold;\">=<\/span> scores<span style=\"color: #333333;\">(<\/span><span style=\"color: #bb0066; font-weight: bold;\">Random<\/span><span style=\"color: #333333;\">.<\/span>nextInt<span style=\"color: #333333;\">(<\/span>scores<span style=\"color: #333333;\">.<\/span>length<span style=\"color: #333333;\">))<\/span>\u00a0 score <span style=\"color: #008800; font-weight: bold;\">match<\/span> <span style=\"color: #333333;\">{<\/span>\r\n  <span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #0000dd; font-weight: bold;\">30<\/span> <span style=\"color: #008800; font-weight: bold;\">=&gt;<\/span> <span style=\"background-color: #fff0f0;\">\"F - Fail\"<\/span>\r\n  <span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #0000dd; font-weight: bold;\">50<\/span> <span style=\"color: #008800; font-weight: bold;\">=&gt;<\/span> <span style=\"background-color: #fff0f0;\">\"C - Good\"<\/span>\r\n  <span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #0000dd; font-weight: bold;\">60<\/span> <span style=\"color: #008800; font-weight: bold;\">=&gt;<\/span> <span style=\"background-color: #fff0f0;\">\"B - Very Good\"<\/span>\r\n  <span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #0000dd; font-weight: bold;\">90<\/span> <span style=\"color: #008800; font-weight: bold;\">=&gt;<\/span> <span style=\"background-color: #fff0f0;\">\"A - Excellent\"<\/span>\r\n<span style=\"color: #333333;\">}<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>In the example, we create a value, score, that gets a random number taken from a sequence of four integers 30, 50, 60 and 90. <strong><em>score<\/em><\/strong> now becomes the left operand of the match operator and on the right we have an expression with four cases. Also note the the match expression is a value that can be assigned.<\/p>\n<ol>\n<li><a href=\"#t1\">Matching Case Classes<\/a><\/li>\n<li><a href=\"#t2\">Matching on Types Only<\/a><\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<h4><strong id=\"t1\">1. Matching Case Classes<\/strong><\/h4>\n<p>Pattern matching is normally applied in case classes. Let&#8217;s assume we have this representation:<\/p>\n<pre style=\"margin: 0; line-height: 125%;\">type  Message =\r\n      Email String String String\r\n    | SMS String String\r\n    | AudioMemo String String\r\n    | Letter\r\n<\/pre>\n<p>This is and Elm syntax. <a href=\"https:\/\/kindsonthegenius.com\/elm\/\" target=\"_blank\" rel=\"noopener\">You can learn Elm here<\/a>.<\/p>\n<p>The means that we have four classes: Email, SMS, AudioMemo and Letter. All of them are derived from Message. Also, the parameters for the classes are specified against each of them.<\/p>\n<p>The Scala equivalent for this is given below:<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008800; font-weight: bold;\">sealed<\/span> <span style=\"color: #008800; font-weight: bold;\">trait<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Message\r\n<\/span>\r\n<span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #008800; font-weight: bold;\">class<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Email<\/span> <span style=\"color: #333333;\">(<\/span>sender<span style=\"color: #008800; font-weight: bold;\">:<\/span><span style=\"color: #333399; font-weight: bold;\">String<\/span><span style=\"color: #333333;\">,<\/span> title<span style=\"color: #008800; font-weight: bold;\">:<\/span> <span style=\"color: #333399; font-weight: bold;\">String<\/span><span style=\"color: #333333;\">,<\/span> body<span style=\"color: #008800; font-weight: bold;\">:<\/span> <span style=\"color: #333399; font-weight: bold;\">String<\/span><span style=\"color: #333333;\">)<\/span> <span style=\"color: #008800; font-weight: bold;\">extends<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Message<\/span>\r\n<span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #008800; font-weight: bold;\">class<\/span> <span style=\"color: #bb0066; font-weight: bold;\">SMS<\/span> <span style=\"color: #333333;\">(<\/span>caller<span style=\"color: #008800; font-weight: bold;\">:<\/span><span style=\"color: #333399; font-weight: bold;\">String<\/span><span style=\"color: #333333;\">,<\/span> message<span style=\"color: #008800; font-weight: bold;\">:<\/span> <span style=\"color: #333399; font-weight: bold;\">String<\/span><span style=\"color: #333333;\">)<\/span> <span style=\"color: #008800; font-weight: bold;\">extends<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Message<\/span>\r\n<span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #008800; font-weight: bold;\">class<\/span> <span style=\"color: #bb0066; font-weight: bold;\">AudioMemo<\/span> <span style=\"color: #333333;\">(<\/span>contact<span style=\"color: #008800; font-weight: bold;\">:<\/span><span style=\"color: #333399; font-weight: bold;\">String<\/span><span style=\"color: #333333;\">,<\/span> link<span style=\"color: #008800; font-weight: bold;\">:<\/span> <span style=\"color: #333399; font-weight: bold;\">String<\/span><span style=\"color: #333333;\">)<\/span> <span style=\"color: #008800; font-weight: bold;\">extends<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Message<\/span>\r\n<span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #008800; font-weight: bold;\">class<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Letter<\/span><span style=\"color: #333333;\">()<\/span> <span style=\"color: #008800; font-weight: bold;\">extends<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Message<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Now, we would like to display a custom message based on the particular class. Therefore we would do pattern matching on the base class, Message. We&#8217;ll write a function that would take an argument of type Message and display a particular output based on which implementation of message it is.<\/p>\n<p>The function is given below:<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008800; font-weight: bold;\">def<\/span> showMessage <span style=\"color: #008800; font-weight: bold;\">=<\/span> <span style=\"color: #333333;\">(<\/span>a<span style=\"color: #008800; font-weight: bold;\">:<\/span> <span style=\"color: #333399; font-weight: bold;\">Message<\/span><span style=\"color: #333333;\">)<\/span> <span style=\"color: #008800; font-weight: bold;\">=&gt;<\/span> <span style=\"color: #333333;\">{<\/span>\r\n  a <span style=\"color: #008800; font-weight: bold;\">match<\/span> <span style=\"color: #333333;\">{<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Email<\/span><span style=\"color: #333333;\">(<\/span>sender<span style=\"color: #333333;\">,<\/span> title<span style=\"color: #333333;\">,<\/span> <span style=\"color: #008800; font-weight: bold;\">_<\/span><span style=\"color: #333333;\">)<\/span> <span style=\"color: #008800; font-weight: bold;\">=&gt;<\/span> <span style=\"color: #333333;\">{<\/span>\r\n      println<span style=\"color: #333333;\">(<\/span>s<span style=\"background-color: #fff0f0;\">\"You received a mail from $sender with $title\"<\/span><span style=\"color: #333333;\">)<\/span>\r\n    <span style=\"color: #333333;\">}<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #bb0066; font-weight: bold;\">SMS<\/span><span style=\"color: #333333;\">(<\/span>caller<span style=\"color: #333333;\">,<\/span> message<span style=\"color: #333333;\">)<\/span> <span style=\"color: #008800; font-weight: bold;\">=&gt;<\/span> <span style=\"color: #333333;\">{<\/span>\r\n      println<span style=\"color: #333333;\">(<\/span>s<span style=\"background-color: #fff0f0;\">\"An SMS arrived from $caller. Message: $message\"<\/span><span style=\"color: #333333;\">)<\/span>\r\n    <span style=\"color: #333333;\">}<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #bb0066; font-weight: bold;\">AudioMemo<\/span><span style=\"color: #333333;\">(<\/span>name<span style=\"color: #333333;\">,<\/span> link<span style=\"color: #333333;\">)<\/span> <span style=\"color: #008800; font-weight: bold;\">=&gt;<\/span> <span style=\"color: #333333;\">{<\/span>\r\n      println<span style=\"color: #333333;\">(<\/span>s<span style=\"background-color: #fff0f0;\">\"Audio message from $name available here: $link\"<\/span><span style=\"color: #333333;\">)<\/span>\r\n    <span style=\"color: #333333;\">}<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Letter<\/span><span style=\"color: #333333;\">()<\/span> <span style=\"color: #008800; font-weight: bold;\">=&gt;<\/span> <span style=\"color: #333333;\">{<\/span>\r\n      println<span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"Please check your postbox\"<\/span><span style=\"color: #333333;\">)<\/span>\r\n    <span style=\"color: #333333;\">}<\/span>\r\n  <span style=\"color: #333333;\">}<\/span>\r\n<span style=\"color: #333333;\">}<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Now we can call the function by and pass in a message type like so:<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008800; font-weight: bold;\">val<\/span> myMail <span style=\"color: #008800; font-weight: bold;\">=<\/span> <span style=\"color: #008800; font-weight: bold;\">new<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Email<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"Kindson\"<\/span><span style=\"color: #333333;\">,<\/span> <span style=\"background-color: #fff0f0;\">\"Hello\"<\/span><span style=\"color: #333333;\">,<\/span> <span style=\"background-color: #fff0f0;\">\"Love you\"<\/span> <span style=\"color: #333333;\">)<\/span>\r\nshowMessage<span style=\"color: #333333;\">(<\/span>myMail<span style=\"color: #333333;\">)<\/span>\r\n\r\n<span style=\"color: #008800; font-weight: bold;\">val<\/span> myLetter <span style=\"color: #008800; font-weight: bold;\">=<\/span> <span style=\"color: #008800; font-weight: bold;\">new<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Letter<\/span><span style=\"color: #333333;\">()<\/span>\r\nshowMessage<span style=\"color: #333333;\">(<\/span>myLetter<span style=\"color: #333333;\">)<\/span>\r\n<\/pre>\n<p>I recommend you run this code yourself and see what the output looks like.<\/p>\n<p>&nbsp;<\/p>\n<h4><strong id=\"t2\">2. Matching on Only Types<\/strong><\/h4>\n<p>In the example given in the preceding section, did pattern matching on the types as well as the arguments. But we can also perform pattern matching based on only the types. The code below illustrates that. Assuming we have two case classes Phone and Tablet that extends Device as shown below.<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008800; font-weight: bold;\">sealed<\/span> <span style=\"color: #008800; font-weight: bold;\">trait<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Device<\/span>\r\n\r\n<span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #008800; font-weight: bold;\">class<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Phone<\/span><span style=\"color: #333333;\">(<\/span>make<span style=\"color: #008800; font-weight: bold;\">:<\/span> <span style=\"color: #333399; font-weight: bold;\">String<\/span><span style=\"color: #333333;\">)<\/span> <span style=\"color: #008800; font-weight: bold;\">extends<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Device<\/span>\r\n<span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #008800; font-weight: bold;\">class<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Tablet<\/span><span style=\"color: #333333;\">(<\/span>make<span style=\"color: #008800; font-weight: bold;\">:<\/span> <span style=\"color: #333399; font-weight: bold;\">String<\/span><span style=\"color: #333333;\">)<\/span> <span style=\"color: #008800; font-weight: bold;\">extends<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Device<\/span>\r\n<span style=\"color: #008800; font-weight: bold;\">case<\/span> <span style=\"color: #008800; font-weight: bold;\">class<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Laptop<\/span><span style=\"color: #333333;\">(<\/span>make<span style=\"color: #008800; font-weight: bold;\">:<\/span> <span style=\"color: #333399; font-weight: bold;\">String<\/span><span style=\"color: #333333;\">)<\/span> <span style=\"color: #008800; font-weight: bold;\">extends<\/span> <span style=\"color: #bb0066; font-weight: bold;\">Device<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Now we write a function that returns a string based on the implementation of the device. Note the structure of the case statement that no argument was used<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"> <span style=\"color: #008800; font-weight: bold;\">def<\/span> tellMe<span style=\"color: #333333;\">(<\/span>device<span style=\"color: #008800; font-weight: bold;\">:<\/span> <span style=\"color: #333399; font-weight: bold;\">Device<\/span><span style=\"color: #333333;\">)<\/span> <span style=\"color: #008800; font-weight: bold;\">=<\/span> device <span style=\"color: #008800; font-weight: bold;\">match<\/span> <span style=\"color: #333333;\">{<\/span>\r\n   <span style=\"color: #008800; font-weight: bold;\">case<\/span>  p<span style=\"color: #008800; font-weight: bold;\">:<\/span><span style=\"color: #333399; font-weight: bold;\">Phone<\/span> <span style=\"color: #333333;\">=&gt;<\/span> <span style=\"background-color: #fff0f0;\">\"This is a phone\"<\/span>\r\n   <span style=\"color: #008800; font-weight: bold;\">case<\/span> t<span style=\"color: #008800; font-weight: bold;\">:<\/span><span style=\"color: #333399; font-weight: bold;\">Tablet<\/span> <span style=\"color: #333333;\">=&gt;<\/span> <span style=\"background-color: #fff0f0;\">\"This is a tablet\"<\/span>\r\n   <span style=\"color: #008800; font-weight: bold;\">case<\/span> l<span style=\"color: #008800; font-weight: bold;\">:<\/span><span style=\"color: #333399; font-weight: bold;\">Laptop<\/span> <span style=\"color: #333333;\">=&gt;<\/span> <span style=\"background-color: #fff0f0;\">\"This is a laptop\"<\/span>\r\n <span style=\"color: #333333;\">}<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Pattern matching allows you to check a value against a given pattern. It is similar to Java and C++ switch statement, but it&#8217;s more powerful. &hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[54],"class_list":["post-281","post","type-post","status-publish","format-standard","hentry","category-scala-programming","tag-pattern-matching"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.kindsonthegenius.com\/scala\/wp-json\/wp\/v2\/posts\/281","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kindsonthegenius.com\/scala\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kindsonthegenius.com\/scala\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kindsonthegenius.com\/scala\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kindsonthegenius.com\/scala\/wp-json\/wp\/v2\/comments?post=281"}],"version-history":[{"count":2,"href":"https:\/\/www.kindsonthegenius.com\/scala\/wp-json\/wp\/v2\/posts\/281\/revisions"}],"predecessor-version":[{"id":283,"href":"https:\/\/www.kindsonthegenius.com\/scala\/wp-json\/wp\/v2\/posts\/281\/revisions\/283"}],"wp:attachment":[{"href":"https:\/\/www.kindsonthegenius.com\/scala\/wp-json\/wp\/v2\/media?parent=281"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kindsonthegenius.com\/scala\/wp-json\/wp\/v2\/categories?post=281"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kindsonthegenius.com\/scala\/wp-json\/wp\/v2\/tags?post=281"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}