title: Ada-like types in Nimrod
body: <p>today I did ask in D mailing list whether it's possible to define and use custom data types in a way similar to e.g. example from Ada's <a href="http://en.wikipedia.org/wiki/Ada_%28programming_language%29">wiki</a> page:</p>
  
  <pre><code>type Day_type   is range    1 ..   31;
  type Month_type is range    1 ..   12;
  type Year_type  is range 1800 .. 2100;
  type Hours is mod 24;
  type Weekday is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday); 
  
  
  type Date is
     record
       Day   : Day_type;
       Month : Month_type;
       Year  : Year_type;
     end record;
  
  subtype Working_Hours is Hours range 0 .. 12;
  subtype Working_Day is Weekday range Monday .. Friday;
  Work_Load: constant array(Working_Day) of Working_Hours 
     := (Friday =&gt; 6, Monday =&gt; 4, others =&gt; 10); 
  </code></pre>
  
  <p>and the <a href="http://forum.dlang.org/thread/vqsnloitqvouoahdngzb@forum.dlang.org?page=14#post-qhneezraycclrkqxfrvh:40forum.dlang.org">reply</a> demonstrated something like:</p>
  
  <pre><code>import std.typecons;
  import std.exception;
  
  struct Limited(T, T lower, T upper)
  {
      T _t;
      mixin Proxy!_t; //Limited acts as T (almost)
      invariant()
      {
          enforce(_t &gt;= lower &amp;&amp; _t &lt;= upper);
      }
      this(T t)
      {
          _t = t;
      }
  }
  
  auto limited(T, T lower, T upper)(T init = T.init)
  {
      return Limited!(T, lower, upper)(init);
  }
  
  unittest
  {
      enum l = [-4,9];
      auto a = limited!(int, l[0], l[1])();
      foreach(i; l[0] .. l[1]+1)
      {
          a = i;
      }
  
      assertThrown({a = -5;}());
      assertThrown({a = 10;}());
  }
  </code></pre>
  
  <p>which shows it's possible, but probably misses Ada's elegance.</p>
  
  <p>Now, after reading about Nimrod recently, I wonder how it can handle similar task with the provision to ensure same Ada's type-safety?</p>