Algebraic Data Types

Algebraic Data Types

What's the so-called ADT?

Example: Describe arithmetic operations

using MLStyle
@data Arith begin 
    Number(v :: Int)
    Minus(fst :: Arith, snd :: Arith)
    Mult(fst :: Arith, snd :: Arith)
    Divide(fst :: Arith, snd :: Arith)
end

Above codes makes a clarified description about Arithmetic and provides a corresponding implementation.

If you want to transpile above ADTs to some specific language, there is a clear step:


eval_arith(arith :: Arith) = 
    let wrap_op(op)  = (a, b) -> op(eval_arith(a), eval_arith(b)),
        (+, -, *, /) = map(wrap_op, (+, -, *, /))
        @match arith begin
            Number(v)       => v
            Minus(fst, snd) => fst - snd
            Mult(fst, snd)   => fst * snd
            Divide(fst, snd) => fst / snd
        end
    end

eval_arith(
    Minus(
        Number(2), 
        Divide(Number(20), 
               Mult(Number(2), 
                    Number(5)))))
# => 0

Case Class

Just like the similar one in Scala

abstract type A end
@case C{T}(a :: Int, b)
@case D(a, b)
@case E <: A

In terms of data structure definition, following codes could be expanded to

abstract type A end
struct C{T}
    a :: Int
    b
end

struct D
    a
    b
end

struct E <: A
end

<additional codes>

Take care that any instance of E is a singleton thanks to Julia's language design pattern.

However the two snippet above are not equivalent, for there are other hidden details to support pattern matching on these data structures.

See pattern.md.