<br><br><div class="gmail_quote">On Sun, Apr 11, 2010 at 1:59 AM, Andrew U. Frank <span dir="ltr">&lt;<a href="mailto:frank@geoinfo.tuwien.ac.at">frank@geoinfo.tuwien.ac.at</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
in modeling real application we have often the case that the type of<br>
some object depends on a value. e.g. small_boat is a vessel with size<br>
less than a constant. big_boat is a vessel with a larger size. for<br>
example, many legal classifications are expressed in this form (e.g. car<br>
vs. truck)<br>
depending on the type, operations are applicable or not (e.g. road with<br>
restriction &#39;no trucks&#39;).<br>
how could one model such situations in haskell? i assume there are<br>
several possibilities...<br>
<div><div></div><div class="h5"><br></div></div></blockquote><div><br></div><div>The two main ways I can think of for this use typeclasses or witness types.</div><div><br></div><div>The type class way is like this:</div>
<div>class Vehicle a where</div><div><br></div><div>data Car</div><div>data Truck</div><div><br></div><div>instance Vehicle Car where</div><div>instance Vehicle Truck where</div><div><br></div><div>Now you can have things that take a Car or a Truck or they can take a Vehicle instead.</div>
<div><br></div><div>moveVehicle :: Vehicle v =&gt; v -&gt; Simulation ()</div><div><br></div><div>carsOnly :: Car -&gt; ...</div><div><br></div><div>If you want to understand this approach better, I think this is how HList works to some extent.  For example, see their HBool type class.</div>
<div><br></div><div>Or, you could use witness types:</div><div><br></div><div>data Vehicle classification = Vehicle { ... }</div><div><br></div><div>mkCar :: Vehicle Car</div><div>mkTruck :: Vehicle Truck</div><div><br></div>
<div>Then you would export the smart constructors, (mkCar/mkTruck) without exporting the Vehicle constructor.</div><div><br></div><div>moveVehicle :: Vehicle c -&gt; Simulation ()</div><div>carsOnly :: Vehicle Car -&gt; ...</div>
<div><br></div><div>In the witness type version you may find that defining Vehicle as a GADT is even better:</div><div><br></div><div>data Vehicle classification where</div><div>  mkCar :: ... -&gt; Vehicle Car</div><div>
  mkTruck :: ... -&gt; Vehicle Truck</div><div><br></div><div>This is nice because it&#39;s direct and when you pattern match on the constructor you recover the type of classification.  For example, I believe this would type check:</div>
<div><br></div><div>foo :: Vehicle c -&gt; c</div><div>foo (mkCar ...) = Car</div><div>foo (mkTruck ...) = Truck</div><div>  </div><div>(Note: I didn&#39;t test any of the above, so I could have errors/typos.)</div><div><br>
</div><div>Jason</div></div>