Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partial functions in SML with user data types

I want to create partial functions that enable values of the same unit and dimension to be added and multiplied, so far I've got the following type definitions, I also need to include units conversion. This allows adding values of the same unit but with different dimensions. I don't need all eventualities, just those that are compatible. For example:

 datatype temp_dimension = Celsius | Fahrenheit; 
 datatype dist_dimension = Meters | Centimeters | Kilometers; 
 datatype units = Temp of temp_dimension | Distance of dist_dimension;
 type value = (real * units);

Example use:

add ((3.5, Temp (Celsius)), (4.5, Temp (Celsius)))
=> (8.0, Temp (Celsius))
mul ((2.0, Distance (Meters)), (3.0, Distance (Meters)))
=> (6.0, Distance (Meters))
add ((2.0, Distance (Meters)), (3.0, Distance (Centimetres)))
=> (2.03, Distance (Meters))

I have tried this code:

fun add (x1, y1) (x2, y2) = 
  ((x1 + x2) + y2)) add Temp(Celsius); 

fun mul (x1, y1) (x2, y2) = 
   ((x1 * x2) + y2);
like image 881
user3330146 Avatar asked Aug 06 '26 08:08

user3330146


1 Answers

A partial function is a function which is not defined for all possible inputs. In your case, neither add nor mul are defined when trying to call them with units of incompatible types. For example, if you'd try to add Celsius and Meters values. In that case, the only reasonable approach would be to throw an exception.

So, here's a skeleton to get you started:

fun add ((v1, Temp t1), (v2, Temp t2)) = addTemp ((v1, t1), (v2, t2))
  | add ((v1, Distance d1), (v2, Distance d2)) = addDist ((v1, d1), (v2, d2))
  | add _ = raise Fail "incompatible units in addition"

fun mul ((v1, Temp t1), (v2, Temp t2)) = mulTemp ((v1, t1), (v2, t2))
  | mul ((v1, Distance d1), (v2, Distance d2)) = mulDist ((v1, d1), (v2, d2))
  | mul _ = raise Fail "incompatible units in multiplication"
like image 173
Ionuț G. Stan Avatar answered Aug 08 '26 09:08

Ionuț G. Stan