{"id":961,"date":"2013-12-21T09:58:53","date_gmt":"2013-12-21T09:58:53","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=961"},"modified":"2013-12-21T10:36:41","modified_gmt":"2013-12-21T10:36:41","slug":"modules-in-f","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/modules-in-f\/","title":{"rendered":"Modules in F#"},"content":{"rendered":"<p>Modules allow us to break up source code into multiple files. There are two types of module, a <strong>top-level<\/strong> module and <strong>local<\/strong> modules.<\/p>\n<p><em>Note: I&#8217;ve omitted any namespaces, but for completeness of this post, a name space would be added as the first line in the module files (if required) as per<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nnamespace MyNamespace\r\n\r\nmodule MyModule =\r\n   let square x = x * x\r\n<\/pre>\n<p><\/em><\/p>\n<p><strong>The top-level module<\/strong><\/p>\n<p>The top-level module is basically a module which contains all the code for an application and it has slightly different rules regarding it&#8217;s layout compared to the local modules (see <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd233221.aspx\" title=\"Modules (F#)\" target=\"_blank\">Modules (F#)<\/a>.<\/p>\n<p>Reproducing a little from the above link we see that a top-level module does not need an = sign at the end of the module name and declarations need not be indented, for example the following is perfectly acceptable in a top-level module but not a local module<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmodule MyModule\r\n\r\nlet hello = \r\n   printfn &quot;Hello&quot;\r\n<\/pre>\n<p><strong>Local Modules<\/strong><\/p>\n<p>Local modules are basically re-usable files. The usual usage would be to group together related code. Unlike the top-level module, local modules require indented formatting as well as an = after the module name, so the previously define code for a top-level module would look like the following code in a local module<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmodule MyModule =\r\n\r\n   let hello =\r\n      printfn &quot;Hello&quot;\r\n<\/pre>\n<p><strong>The Program\/EntryPoint module<\/strong><\/p>\n<p>By default the code generated by Visual Studio as the starting point for an F# applications looks like<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\n&#x5B;&lt;EntryPoint&gt;]\r\nlet main argv = \r\n    printfn &quot;%A&quot; argv\r\n    0 \/\/ return an integer exit code\r\n<\/pre>\n<p>But implicitly this will be compiled as<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmodule Program\r\n&#x5B;&lt;EntryPoint&gt;]\r\nlet main argv = \r\n    printfn &quot;%A&quot; argv\r\n    0 \/\/ return an integer exit code\r\n<\/pre>\n<p>Thus conversely the module name of a top-level module can be omitted if it&#8217;s the only file in the application.<\/p>\n<p><strong>Inner Modules<\/strong><\/p>\n<p>Not only can a file be declared as a module but you can also have modules nested within modules, for example<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmodule GrandParent =\r\n   module Parent =\r\n      module Child =\r\n         let x = 100\r\n<\/pre>\n<p>Within a top-level module we can define this as <\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nmodule GrandParent\r\n\r\nmodule Parent =\r\n   module Child =\r\n      let x = 100\r\n<\/pre>\n<p>in other words the top level module does not need the = sign or the indenting of the Parent module.<\/p>\n<p><strong>How to use a module<\/strong><\/p>\n<p>So we&#8217;ve shown how to declare modules but at some point we need to use them, to achieve this we use the following<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nopen MyModule\r\n<\/pre>\n<p>If we&#8217;d had a namespace we could open the namespace such as <em>open MyNamespace<\/em>. In such a case where modules were in the namespace we could prefix them on the functions, such as <em>MyModule.square 3<\/em>. Alternatively we could open the namespace and specific module(s) such as <em>open MyNamespace.MyModule<\/em> and thus have no need to prefix the functions with the module name.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Modules allow us to break up source code into multiple files. There are two types of module, a top-level module and local modules. Note: I&#8217;ve omitted any namespaces, but for completeness of this post, a name space would be added as the first line in the module files (if required) as per namespace MyNamespace module [&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":[6],"tags":[],"class_list":["post-961","post","type-post","status-publish","format-standard","hentry","category-f"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/961","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=961"}],"version-history":[{"count":8,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/961\/revisions"}],"predecessor-version":[{"id":969,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/961\/revisions\/969"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=961"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=961"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=961"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}