{"id":8267,"date":"2020-06-16T21:07:24","date_gmt":"2020-06-16T21:07:24","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=8267"},"modified":"2020-06-16T21:07:24","modified_gmt":"2020-06-16T21:07:24","slug":"creating-types-in-haskell","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/creating-types-in-haskell\/","title":{"rendered":"Creating types in Haskell"},"content":{"rendered":"<p>In most programming language we need ways to declare our own types. These help with readability, modularity etc. Haskell is no different in offering these capabilities.<\/p>\n<p>We can create a simple data type using the <em>data<\/em> keyword, followed by either of available values (in C# this would be similar to an enum). So here&#8217;s the definition of a Boolean type<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\ndata Bool = False | True\r\n<\/pre>\n<p>The values after the = are the <em>value constructors<\/em> with the | being like an <em>or<\/em>, hence this Bool have either False or True value. <\/p>\n<p><em>Note: The type name and the value constructor must be capital cased.<\/em><\/p>\n<p>We can also declare types more like structs\/classes in that we can define the field types that make up the type. For example here&#8217;s a Point type<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\ndata Point = Point Integer Integer\r\n<\/pre>\n<p>In this example we could create a point as follows<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npt = Point 1 2\r\n<\/pre>\n<p>Accessing these values can be a little verbose (especially when we might have lots of fields) because of the lack of any names, hence we&#8217;d use pattern matching, i.e. <\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nxpt :: Point -&gt; Integer\r\nxpt (Point x _) = x\r\n\r\n-- example of printing the x value of value pt of type Point\r\nprint (xpt pt)\r\n<\/pre>\n<p><em>Note: The type annotation is not required and the underscore is a discard, hence is ignored.<\/em><\/p>\n<p>We can combine types just as we combined False and True into essentially a union. So for example here we have a data type Shape with constructors for Circle and Triangle.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\ndata Shape = Triangle Int Int Int | Circle Int\r\n\r\ntriangle = Triangle 1 2 3\r\ncircle = Circle 4\r\n<\/pre>\n<p>It&#8217;s not clear what these fields of the constructors mean, so let&#8217;s add some names which also allows us to more easily access specific values from the data (i.e. fixes the issue with using pattern matching &#8211; which ofcourse is still a valid way of doing things).<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\ndata Shape = Triangle { \r\n   hypotenuse :: Int, \r\n   opposite :: Int, \r\n   adjacent :: Int \r\n} | Circle { \r\n  radius :: Int \r\n}\r\n<\/pre>\n<p>We can declare instances of this type using names or without names, for example<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n-- not using names\r\ntriangle = Triangle 1 2 3\r\n-- with names\r\ntriangle1 = Triangle { opposite = 5, hypotenuse = 6, adjacent = 7 }\r\n<\/pre>\n<p>Instead of creating a function to extract a value (like we did with the xpt function we created) we can now use the following<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nprint (hypotenuse triangle)\r\n<\/pre>\n<p>and Haskell essentially creates the function for us, i.e. using the REPL along with <em>:t hypotenuse<\/em> we get the following<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nhypotenuse :: Shape -&gt; Int\r\n<\/pre>\n<p>Haskell is immutable, so how do we make changes to an instance of data? Well we &#8220;copy and update&#8221;. Thankfully Haskell makes this easy (so we don&#8217;t have to literally create copies of every field on our data and then change values).<\/p>\n<p>If you&#8217;ve used JavaScript it&#8217;s like using a spread operator of in F# and <em>with<\/em>.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nnewTriangle = triangle { hypotenuse = 10 } \r\n<\/pre>\n<p>In this case <em>newTriangle<\/em> is a copy of the <em>triangle<\/em> data, with the <em>hypotenuse<\/em> changed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In most programming language we need ways to declare our own types. These help with readability, modularity etc. Haskell is no different in offering these capabilities. We can create a simple data type using the data keyword, followed by either of available values (in C# this would be similar to an enum). So here&#8217;s the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[295],"tags":[],"class_list":["post-8267","post","type-post","status-publish","format-standard","hentry","category-haskell"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/8267","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=8267"}],"version-history":[{"count":2,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/8267\/revisions"}],"predecessor-version":[{"id":8269,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/8267\/revisions\/8269"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=8267"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=8267"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=8267"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}