A new case x is defined with
case x
and when it has a parameter with
case y(number)
Examples:
case age(number)case rgb [number, number, number]case myrecord { name : string, address : string }With case several things are defined at once:
x, or y(40)y(10) and y(8+2) are equal)y^ (e.g. y^(y(40)) returns 40)f^-1 for the inverse function in mathematicsx, or y(arg)x, or y(number)When a case has a parameter, it is enforced that the parameter has the specified type. After defining y(number) it is e.g. never possible to put anything else into the case than a number.
If a case is declared as private, the constructor cannot be called from outside the module. That way the module has full control over possible representations. E.g.
module color
private case rgb(data)
type t = rgb(data) // "type t = rgb" is permitted as notational abbreviation
private def clamp =
(x -> if (x < 0) 0 else if (x > 255) 255 else x)
def create : number -> number -> number -> t
def create =
((r,g,b) -> rgb([clamp(r), clamp(g), clamp(b)]))
def red : t -> number
def red(col) = col |> rgb^ |> (triple -> triple[0])
def green : t -> number
def green(col) = col |> rgb^ |> (triple -> triple[1])
def blue : t -> number
def blue(col) = col |> rgb^ |> (triple -> triple[2])
def add : t -> t -> t
def add =
((col1, col2) ->
create(red(col1)+red(col2), green(col1)+green(col2), blue(col1)+blue(col2))
)
module end
It is still allowed to access the inner value of private cases. In particular, the deconstructor color.rgb^ is callable, and you can also pattern-match from outside the module.
dataAny parameterless case, and any case with a parameter that is a subtype of data is also considered as a subtype of data:
color.rgb would be datacase fun(S -> T) would not be data because the parameter is a functionThis means that you can treat such cases as data:
cell mycol : data = color.create(12,45,198)
You can get the original type back with a type assertion:
cell realcol : color.t = mycol |> type(color.t)