(This is a post for CS320 Boston University)

Recall that a type can be seen as a value space. We also mentioned algebric data type, specifically sum types.

Abstract Types

In ATS, we encourage programmers to think in an abstract way, to program towards your goal, instead of paying great attention to details at the very beginning. Therefore ATS provides abstract types.

abstype money

The above code introduces a type. It has a name mytype, but it has no concrete value space associated to it. You can now use the type to write your interface,

fun get_cent (money): int
fun get_dollar (money): int
fun make_money (dollar: int, cent: int): money

fun money_to_cent (money): int
fun cent_to_money (int): money

and use the interface to write the program.

implement money_to_cent (m) = get_dollar (m) * 100 + get_cent (m)
implement cent_to_money (c) = make_money (c / 100, c mod 100)

As you can see, the detail of money is completely unknown, so are the first three interfaces. But you can still write programs like the implemtations of the last two interfaces.

However, the implementation of the first three functions, have to know the details of money.

datatype money_type = M of (int, int)
assume money = money_type

Here, we define a sum type money_type with only one varient M. This is a concrete type. We then use assume to associate the value space of money_type to money to make it concrete. From now on, we can implement those functions.

implement get_cent (m) = c where M(_, c) = m
implement get_dollar (m) = d where M(d, _) = m
implement make_money (d, c) = M(d, c)

The benefit here is that you can change your implementation as you want. You just need to assume it to another concrete type, and implement these three functions again based on the new associated value space.

Exercise

Suppose we have an integer arithmatic expression to be evaluated. Please write your implementation based on abstract types and interfaces.

abstype exp

fun get_num (exp): int
fun is_num (exp): bool
fun is_add (exp): bool
fun is_sub (exp): bool
fun fst (exp): exp      // e.g. (pseudo) fst ("1+2") = "1"
fun snd (exp): exp      // e.g. (pseudo) snd ("1+2") = "2"

fun eval (exp): int     // please implement this

And based on the following code

datatype exp_type = 
    | num of (int)
    | add of (exp_type, exp_type)
    | sub of (exp_type, exp_type)
    | par of (exp_type)
assume exp = exp_type

write the implementations for the first five functions.