{"id":5834,"date":"2020-01-17T07:23:26","date_gmt":"2020-01-17T07:23:26","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-20-concepts-defining-concepts\/"},"modified":"2023-06-26T09:56:07","modified_gmt":"2023-06-26T09:56:07","slug":"c-20-concepts-defining-concepts","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-20-concepts-defining-concepts\/","title":{"rendered":"C++20: Define Concepts"},"content":{"rendered":"<p>With this post, I start my last fascinating topic to concepts: define your concepts. Consequentially, I answer the questions I opened in previous posts.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5808\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts.png\" alt=\"TimelineCpp20Concepts\" width=\"650\" height=\"255\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts.png 954w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts-300x118.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts-768x301.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>First and foremost, most of the concepts I define are already available in the C++ 20 draft. Therefore, there is no need to define them. To distinguish my concepts from the predefined concepts, I capitalize them. My previous post gave an overview of the predefined concepts:<a href=\"http:\/\/bit.ly\/2TijbbD\"> C++20: Concepts &#8211; Predefined Concepts<\/a>.<\/p>\n<h2>Defining concepts<\/h2>\n<p>There are two typical ways to define concepts: direct definition or requires-expressions.&nbsp;<\/p>\n<h3>Direct definition<\/h3>\n<p>The syntactic form changed a little bit from the syntax based on the concepts TS (Technical Specification) to the proposed syntax for the C++20 standard.&nbsp;<\/p>\n<h4>Concepts TS<\/h4>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept <span style=\"color: #007788; font-weight: bold;\">bool<\/span> Integral(){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> std<span style=\"color: #555555;\">::<\/span>is_integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;\r\n}\r\n<\/pre>\n<\/div>\n<h4>C++20 standard&nbsp;<\/h4>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept Integral <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>is_integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The C++20 standard syntax is less verbose. Both used under the hood the function <span style=\"font-family: 'courier new', courier;\">std::is_integral&lt;T&gt;::value<\/span> from the C++11&nbsp;<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/type_traits\">type-traits library<\/a>. <span style=\"font-family: 'courier new', courier;\">T<\/span> fulfills the concept if the compile-time predicate <span style=\"font-family: 'courier new', courier;\">std::integral&lt;T&gt;::value<\/span> evaluates to <span style=\"font-family: 'courier new', courier;\">true<\/span>. Compile-time predicate means that the function runs at compile-time and returns a boolean. Since C++17, you can write<span style=\"font-family: 'courier new', courier;\"> std::integral&lt;T&gt;::value<\/span> less verbose: <span style=\"font-family: 'courier new', courier;\">std::integral_v&lt;T&gt;.&nbsp;<\/span><\/p>\n<p>I&#8217;m unsure if the two terms <strong>variable concept<\/strong>&nbsp;for direct definition and <strong>function concept<\/strong>&nbsp;for requires-expressions are still used. Still, they help to keep the difference between the direct definition and the requires-expressions in mind.&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>I skip the example to the usage of the concept<span style=\"font-family: 'courier new', courier;\"> Integral<\/span>. If you are curious, read my previous post: <a href=\"http:\/\/bit.ly\/2RArE9c\">C++ 20: Concepts, the Placeholder Syntax<\/a>.&nbsp;<\/p>\n<\/p>\n<h3>Requires-expressions<\/h3>\n<p>Analogous to the direct definition, the syntax of requires-expressions also changed from the concepts TS to the proposed draft C++20 standard.&nbsp;<\/p>\n<h4>Concepts TS&nbsp;<\/h4>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept <span style=\"color: #007788; font-weight: bold;\">bool<\/span> Equal(){\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> requires(T a, T b) {\r\n        { a <span style=\"color: #555555;\">==<\/span> b } <span style=\"color: #555555;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span>;\r\n        { a <span style=\"color: #555555;\">!=<\/span> b } <span style=\"color: #555555;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span>;\r\n   };\r\n}\r\n<\/pre>\n<\/div>\n<h4>C++20 standard<\/h4>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept Equal <span style=\"color: #555555;\">=<\/span>\r\n    requires(T a, T b) {\r\n        { a <span style=\"color: #555555;\">==<\/span> b } <span style=\"color: #555555;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span>;\r\n        { a <span style=\"color: #555555;\">!=<\/span> b } <span style=\"color: #555555;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span>;\r\n    };\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>As before, the C++20 syntax is more concise.&nbsp;<span style=\"font-family: 'courier new', courier;\">T<\/span> fulfills the concept if the operator&nbsp;<span style=\"font-family: 'courier new', courier;\">==<\/span> and<span style=\"font-family: 'courier new', courier;\"> !=<\/span>&nbsp;are overloaded and return a boolean. Additionally, the types of <span style=\"font-family: 'courier new', courier;\">a<\/span> and <span style=\"font-family: 'courier new', courier;\">b<\/span> have to be the same.<\/p>\n<h3>The concept Equal<\/h3>\n<p>Now, it&#8217;s time to use the concept <span style=\"font-family: 'courier new', courier;\">Equal<\/span>:&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ conceptsDefintionEqual.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept Equal <span style=\"color: #555555;\">=<\/span>\r\n    requires(T a, T b) {\r\n        { a <span style=\"color: #555555;\">==<\/span> b } <span style=\"color: #555555;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span>;\r\n        { a <span style=\"color: #555555;\">!=<\/span> b } <span style=\"color: #555555;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span>;\r\n};\r\n\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #cc00ff;\">areEqual<\/span>(Equal auto a, Equal auto b) {                     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>            \r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> a <span style=\"color: #555555;\">==<\/span> b;\r\n}\r\n\r\n<span style=\"color: #0099ff; font-style: italic;\">\/*<\/span>\r\n\r\n<span style=\"color: #0099ff; font-style: italic;\">struct WithoutEqual{<\/span>\r\n<span style=\"color: #0099ff; font-style: italic;\">  bool operator==(const WithoutEqual&amp; other) = delete;<\/span>\r\n<span style=\"color: #0099ff; font-style: italic;\">};<\/span>\r\n\r\n<span style=\"color: #0099ff; font-style: italic;\">struct WithoutUnequal{<\/span>\r\n<span style=\"color: #0099ff; font-style: italic;\">  bool operator!=(const WithoutUnequal&amp; other) = delete;<\/span>\r\n<span style=\"color: #0099ff; font-style: italic;\">};<\/span>\r\n\r\n<span style=\"color: #0099ff; font-style: italic;\">*\/<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>boolalpha <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"areEqual(1, 5): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> areEqual(<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">5<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  <span style=\"color: #0099ff; font-style: italic;\">\/*<\/span>\r\n<span style=\"color: #0099ff; font-style: italic;\">  <\/span>\r\n<span style=\"color: #0099ff; font-style: italic;\">  bool res = areEqual(WithoutEqual(),  WithoutEqual());<\/span>\r\n<span style=\"color: #0099ff; font-style: italic;\">  <\/span>\r\n<span style=\"color: #0099ff; font-style: italic;\">  bool res2 = areEqual(WithoutUnequal(),  WithoutUnequal());<\/span>\r\n<span style=\"color: #0099ff; font-style: italic;\">  <\/span>\r\n<span style=\"color: #0099ff; font-style: italic;\">  *\/<\/span>\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">I used the concept of&nbsp;<\/span><span style=\"color: #444444; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; font-family: 'courier new', courier;\">Equal<\/span><span style=\"color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">&nbsp;in the function&nbsp;<\/span><span style=\"color: #444444; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; font-family: 'courier new', courier;\">areEqual<\/span><span style=\"color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">&nbsp;(line 1). To remind you. Using a concept as a function parameter, the compiler creates a function template under the hood, with the concept specified constraints on the parameters. To get more information on this concise syntax, read my post:&nbsp;<a href=\"http:\/\/bit.ly\/2RArE9c\">C++ 20: Concepts, the Placeholder Syntax<\/a>.&nbsp;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">The output is not so exciting:&nbsp;<\/span><span style=\"color: #444444; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; font-family: 'courier new', courier;\"><br \/><\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5832\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/01\/conceptsDefinitionEqual.png\" alt=\"conceptsDefinitionEqual\" width=\"400\" height=\"120\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/01\/conceptsDefinitionEqual.png 455w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/01\/conceptsDefinitionEqual-300x90.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>Now, it has become exciting. What happens if I use the types&nbsp;<span style=\"font-family: 'courier new', courier;\">WithoutEqual<\/span> and <span style=\"font-family: 'courier new', courier;\">WithoutUnequal<\/span>. I intentionally set the<span style=\"font-family: 'courier new', courier;\"> ==&nbsp;<\/span> operator and the <span style=\"font-family: 'courier new', courier;\">!=<\/span> operator to <span style=\"font-family: 'courier new', courier;\">delete<\/span>. The compiler complains immediately that both types do not fulfill the concept of&nbsp;<span style=\"font-family: 'courier new', courier;\">Equal<\/span>.&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5833\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/01\/conceptsDefinitionEqualError.png\" alt=\"conceptsDefinitionEqualError\" width=\"650\" height=\"300\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/01\/conceptsDefinitionEqualError.png 1151w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/01\/conceptsDefinitionEqualError-300x139.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/01\/conceptsDefinitionEqualError-1024x473.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/01\/conceptsDefinitionEqualError-768x355.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>When you look carefully at the error message, you see the reason: <span style=\"font-family: 'courier new', courier;\">(a == b)<\/span> would be ill-formed, and <span style=\"font-family: 'courier new', courier;\">(a != b)<\/span> would be ill-formed.&nbsp;<\/p>\n<p>Before I continue, I have to make a short detour. You can skip the detour if you don&#8217;t want to compile the program.<\/p>\n<h4>The Implementation status of concepts<\/h4>\n<p>I faked the output of the program <span style=\"font-family: 'courier new', courier;\">conceptsDefinitonEqual.cpp<\/span>. The output is from the Concepts TS implementation of GCC. Currently, no C++20 standard-conforming implementation of the concepts syntax is available.<\/p>\n<ul>\n<li>The latest Microsoft compiler supports the C++20 syntax for defining concepts but not the placeholder syntax I used for the function <span style=\"font-family: 'courier new', courier;\">areEqual.<\/span>&nbsp;<\/li>\n<li>The GCC compiler supports the placeholder syntax I used but not the C++20 draft syntax for defining concepts.&nbsp;<\/li>\n<\/ul>\n<h3>From Equal to Ord<\/h3>\n<p>In the previous post, <a href=\"https:\/\/www.modernescpp.com\/index.php\/concepts-two-extrems-and-the-solution\">C++20: Two Extremes and the Rescue with Concepts<\/a>, I mentioned that concepts at first reminded me of Haskell&#8217;s type classes.&nbsp;Type classes in Haskell are interfaces for similar types. The main difference to concepts is, that a type such as <span style=\"font-family: 'courier new', courier;\">Int<\/span>&nbsp;in Haskell has to be an instance of a type class and, therefore, to implement the type class. On the contrary, the compiler checks with concepts if a type fulfills a concept.<span style=\"color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\"><\/span><\/p>\n<p>&nbsp;<\/p>\n<p>Here is a part of the Haskell type class hierarchy.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5814\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/haskellsTypeclasses.png\" alt=\"haskellsTypeclasses\" width=\"500\" height=\"431\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/haskellsTypeclasses.png 749w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/haskellsTypeclasses-300x258.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>This is my crucial observation. Haskell supports the type class <span style=\"font-family: 'courier new', courier;\">Eq<\/span>. When you compare the definition of the type class Eq and the concept Equal, they look quite similar.<\/p>\n<h4>The type class <span style=\"font-family: 'courier new', courier;\">Eq<\/span><\/h4>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #007788; font-weight: bold;\">Eq<\/span> a <span style=\"color: #006699; font-weight: bold;\">where<\/span>\r\n    (<span style=\"color: #555555;\">==<\/span>) <span style=\"color: #000000; font-weight: bold;\">::<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">Bool<\/span>\r\n    (<span style=\"color: #555555;\">\/=<\/span>) <span style=\"color: #000000; font-weight: bold;\">::<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">Bool<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h4>The concept <span style=\"font-family: 'courier new', courier;\">Equal<\/span><\/h4>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept Equal <span style=\"color: #555555;\">=<\/span>\r\n    requires(T a, T b) {\r\n        { a <span style=\"color: #555555;\">==<\/span> b } <span style=\"color: #555555;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span>;\r\n        { a <span style=\"color: #555555;\">!=<\/span> b } <span style=\"color: #555555;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span>;\r\n    };\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Haskell&#8217;s type class requires from its instances, such as <span style=\"font-family: 'courier new', courier;\">Int<\/span>,&nbsp;<\/p>\n<ul style=\"margin-top: 0px; margin-bottom: 10px; color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff;\">\n<li>that they have the equal&nbsp;<span style=\"font-family: 'courier new', courier;\">==<\/span>&nbsp;and inequal&nbsp;<span style=\"font-family: 'courier new', courier;\">\/=<\/span>&nbsp;operation that returns a&nbsp;<span style=\"font-family: 'courier new', courier;\">Bool.<\/span><\/li>\n<li>that both operations take two arguments (<span style=\"font-family: 'courier new', courier;\">a -&gt; a<\/span>) of the same type.<\/li>\n<\/ul>\n<p>Let&#8217;s look once more at the type class hierarchy of Haskell. The type class <span style=\"font-family: 'courier new', courier;\">Ord<\/span> is a refinement of the type class <span style=\"font-family: 'courier new', courier;\">Eq<\/span>. The definition of Ord makes this clear.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #007788; font-weight: bold;\">Eq<\/span> a <span style=\"color: #000000; font-weight: bold;\">=&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">Ord<\/span> a <span style=\"color: #006699; font-weight: bold;\">where<\/span>\r\n    compare <span style=\"color: #000000; font-weight: bold;\">::<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">Ordering<\/span>\r\n    (<span style=\"color: #555555;\">&lt;<\/span>) <span style=\"color: #000000; font-weight: bold;\">::<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">Bool<\/span>\r\n    (<span style=\"color: #555555;\">&lt;=<\/span>) <span style=\"color: #000000; font-weight: bold;\">::<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">Bool<\/span>\r\n    (<span style=\"color: #555555;\">&gt;<\/span>) <span style=\"color: #000000; font-weight: bold;\">::<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">Bool<\/span>\r\n    (<span style=\"color: #555555;\">&gt;=<\/span>) <span style=\"color: #000000; font-weight: bold;\">::<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> <span style=\"color: #007788; font-weight: bold;\">Bool<\/span>\r\n    max <span style=\"color: #000000; font-weight: bold;\">::<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> a <span style=\"color: #000000; font-weight: bold;\">-&gt;<\/span> a\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p style=\"margin: 0px 0px 10px; color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff;\">The most exciting point about the definition of the type class&nbsp;<span style=\"font-family: 'courier new', courier;\">Ord<\/span>&nbsp;is their first line. An instance of the type class&nbsp;<span style=\"font-family: 'courier new', courier;\">Ord<\/span>&nbsp;has to be already an instance of the type class&nbsp;<span style=\"font-family: 'courier new', courier;\">Eq<\/span>.&nbsp;<span style=\"font-family: 'courier new', courier;\">Ordering<\/span>&nbsp;is an enumeration having the values&nbsp;<span style=\"font-family: 'courier new', courier;\">EQ,<\/span>&nbsp;<span style=\"font-family: 'courier new', courier;\">LT,<\/span>&nbsp;and&nbsp;<span style=\"font-family: 'courier new', courier;\">GT. <\/span>This refinement of type classes is exquisite.<\/p>\n<p>Here is the challenge for the next post. Can concepts be refined in a similarly elegant way?&nbsp;<\/p>\n<h2>What&#8217;s next?&nbsp;<\/h2>\n<p style=\"margin: 0px 0px 10px; color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff;\">In my <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-define-the-concept-equal-and-ordering\">next post<\/a>, I accept the challenge to refine the concept of <span style=\"font-family: 'courier new', courier;\">Equal<\/span>. Additionally, I write about the essential concepts <span style=\"font-family: 'courier new', courier;\">Regular<\/span> and <span style=\"font-family: 'courier new', courier;\">Semiregular<\/span>, and I define them.&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>With this post, I start my last fascinating topic to concepts: define your concepts. Consequentially, I answer the questions I opened in previous posts.<\/p>\n","protected":false},"author":21,"featured_media":5808,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[415],"class_list":["post-5834","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-20","tag-concepts"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5834","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5834"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5834\/revisions"}],"predecessor-version":[{"id":6759,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5834\/revisions\/6759"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5808"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5834"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5834"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5834"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}