Skip to main content

Morphir-Typespec Mapping

Morphir to TypeSpec Type Mappings

This is a documentation of the mapping strategy from Morphir types to Typespec types. This document describes how types in Morphir Models are represented in Typespec. Below is a quick overview of the mapping in the table:

TypeTypeSpec TypeComment
Basic Types
Boolboolean
Intint64
Floatfloat64
Stringstring
CharstringNot supported. Mapped to string
Advanced Types
DecimalstringNot supported. Mapped to string
LocalDateplainDate
LocalTimeplainTime
Monthstring
Optional Types
Maybe aa| null
{ foo: Maybe Float, bar: String }{ foo ?: float64, bar: string }Optional Fields are expressed using the ?: syntax
Collection Types
List AArray<A>
Set BArray<B>Not Supported. Mapped to Array
Dict A BArray<[A,B]>Not Supported. Mapped to Array
Composite Types
- Tuple(Int, String)[int64, string]
- ResultResult e v["Err", e] | ["Ok", v]Expressed as tagged unions
- Record{ foo: Int, bar: String }{ foo: int64, bar: string }
- Union TypesFoo Int | Bar String["Foo", int64] | ["Bar, string]
- No Constructor Args (Special Case)Foo | Bar | BazFoo | Bar | BazRepresented as Enum

Basic Types

Bool

Boolean, a true or false value in morphir, maps directly to the boolean type in CADL.

Elm:

type alias IsApplicable = 
Bool

TypeSpec

alias IsApplicable = boolean;
Int

The Int type in morphir is a set of natural numbers(positive and negative) without a fraction component, maps directly to the integer type in cadl.

Elm:

type alias Foo = 
Int

TypeSpec:

alias Foo = int64;

Note:

The integer type assignment is valid in TypeSpec but would default to object when dealing with the OAS emitters.

Float

The Float type; floating point number, in morphir maps directly to the float type in CADL.

Elm:

type alias Pi = 
Float

TypeSpec:

alias Pi = float64;

Note:>

The float type assignment is valid in TypeSpec but would default to object when dealing with the OAS emitters.

String

The String type; a sequence of characters, in morphir maps directly to string type in CADL.

Elm:

type alias Address = 
String

TypeSpec:

alias Address = string ;
Char

The char type is a single character type in morphir and doesn't exist in TypeSpec. An alternative mapping is the string type.

Elm:

type alias AccountGroup = 
Char

TypeSpec:

alias AccountGroup = string;

Advance Types

Decimal

The decimal type in morphir defines a floating point number with accurate precision. This type is not supported directly in CADL and an alternative mapping is the string type.

Elm:

import Morphir.SDK.Decimal exposing (Decimal)

type alias Price =
Decimal

TypeSpec:

alias Price = string
LocalDate

The localDate type in morphir defines as a gregorian date with no timezone information. This type maps directly to plainDate type in CADL.

Elm:

import Morphir.SDK.LocalDate exposing (LocalDate)

type alias DateOfBirth =
LocalDate

TypeSpec:

alias dateOfBirth = plainDate;
LocalTime

The localTime type in morphir defines as basic time without a timezone and its equivalent mapping in CADL is plainTime type.

Elm:

import Morphir.SDK.LocalTime exposing (LocalTime)

type alias CurrentTime =
LocalTime

TypeSpec:

alias currentTime = plainTime;
Month

The morphir type month derived from a localDate was purposefully created to aid in business modeling. This concept of month type does not exist in CADL and the alternative mapping is the string type.

Elm:

import Morphir.SDK.Month exposing (Month)

type alias CurrentMonth =
Month

TypeSpec:

alias purchaseMonth = string;
Optional Values(Maybe)

The maybe type in morphir represents a type that may or may not exist. The type could exist as a standalone type or a field type in a record and both scenarios are supported directly in TypeSpec.

  1. maybe as a standalone type, is presented in cadl as a union of the type or null using the pipe | syntax.

    Elm:

    type alias Foo = 
    Maybe Int

    TypeSpec:

    alias Foo = int64 | null
  2. maybe as a field type in a record, is represented as optional field in a model in TypeSpec using optional field ?: syntax.

    Elm:

    type alias FooBarBaz = 
    { foo: Int
    , bar: Float
    , baz: Maybe String
    }

    TypeSpec:

    model FooBarBaz {
    foo : int64;
    bar : float;
    baz ?: string
    }
  3. In a Scenario where a field type is maybe of another maybe type, it is represented as an optional field of the union type.

    Elm:

    type alias FooBarBaz = 
    { foo: Int
    , bar: Float
    , baz: Maybe (Maybe String)
    }

    TypeSpec:

    model FooBarBaz {
    foo : int64;
    bar : float;
    baz ?: string | null
    }

    Note: \ In the scenario of multiple maybe type for a field in a model, it shall be represented as just the type or null

Collection Types

List

The list type in morphir, is a collection of items of homogeneous type. Its equivalent mapping in CADL is the array type and is defined using the Array<T> syntax where T, is the type.

Elm:

type alias Foo = 
List Int

type alias Bar a =
List a

TypeSpec:

alias Foo = Array<int64>;

alias Bar<A> = Array<A>;
Set

The set type is a collection of items where every item or value is unique. This is not supported directly in CADL hence its alternative mapping is to use the array type.

Elm:

type alias  Foo = 
Set Int

type alias Bar a =
Set a

TypeSpec:

alias Foo = Array<int64>;

alias Bar<A> = Array<A>;
Dict

A dict or dictionary is a collection of unique key-value pairs. In morphir, a dict key could be a simple type such as string, or a complex type such as a custom type. This complex key type is not supported directly in CADL. To achieve such behaviour is to define the dict type as an alias template with the value as an array of tuples.

Elm:

type alias Foo = 
Dict String Int

type alias Bar a b =
Dict a b

TypeSpec

alias Foo = Array<[string,int64]>;

alias Bar<A,B> = Array<[A,B]> ;
Result

The result type in morphir is used to manage errors of a computation that may fail. The morphir type result returns the second argument if successful else it returns the first; which is the error. This concept is supported in CADL through the use of template alias with tagged union types.

Elm:

type alias Foo e v= 
Result e v

TypeSpec:

alias Foo<E,V> = ["Err", E] | ["Ok", V];

Composite Types

Tuples

The tuple type in morphir is data structure that holds elements of the same or different types as a single value. CADL directly support tuples using the [] syntax.

Elm:

type alias Foo = 
( String, Int )

type alias Bar a b =
( a, b )

TypeSpec:

alias Foo = [string, int64];

alias Bar<A,B> = [A, B];
Record Types

Morphir record represents a dictionary of fields where the keys are the field names, and the values are the field values. This maps to model type in CADL. Models are structures with fields called properties and used to represent data schemas.

Elm:

type  alias FooBarBaz = 
{ foo: Int
, bar: String
, baz: Float
}

TypeSpec:

model FooBarBaz {
foo: integer,
bar: string,
baz: float,
}

Custom Types

General Case

A custom type in morphir is a user defined type used to represent a business term or type. This concept is not directly supported in CADL but can be achieved as tagged union of Tuples, where the first element represents type name in string, followed by its arguments.

Elm:

type FooBarBaz 
= Foo Int
| Baz String
| Bar

TypeSpec:

alias FooBarBaz =  ["Foo", int64] | ["Bar", string] | "Baz";   
Special Case

A custom type in morphir whose constructors have no arguments would be represented in CADL as an enum type.

Elm:

type Currency 
= USD
| GBP
| GHS

TypeSpec:

enum Currency {
USD,
GBP,
GHS,
}

Mapping TypeSpec feature concepts to Morphir


CADL TypeMorphir TypeComment
Namespacesnamespace Petstoremodule PetStore exposing (...)Namespaces in CADL map to Modules in Morphir
Modelsmodel Dog { name: string; age: number}type alias Dog = { name: string, age: int}Models in CADL map to Records in Morphir
Enumsenum Direction {East; West; North; South}type Direction
= East | West | North | South
Enums in CADL map to Union Types in Mophir
Union Type
- Unnamed Union
alias Breed = Breagle | GermanShepherd | GoldenRetriever
- Named Union
union Breed {
beagle: Beagle,
shepherd: GermanShepherd.
retiever: GoldenRetriever
}
type Breed
= Beagle Beagle
| Shepherd GermanShepherd
| Retriever GoldenRetriever
Named unions in CADL maps to a Custom Type with a type parameter in Morphir. Any other detail of the type is captured in Morphir's Decorators(Custom Attributes).
NB: unnamed Unions are currently not supported in morphir

Type Relations

Boolean

Boolean in CADL, maps to bool, a true or false value in Morphir.

Integer

In Morphir, this maps to the type int. The integer type assignment is valid CADL, but \ Note:

  1. When dealing with emitters such as OpenApiSpec(OAS) it defaults to an object. To obtain an actual int value, specify a subtype int64.
Float

The float type in CADL, maps directly to type float in Morphi. Same issues with integer type is applicable

String

The string type, in CADL maps directly to string type in Morphir, a sequence of characters,

PlainDate

PlainDate type in CADL, maps to localDate type in morphir, defined as a gregorian date with no timezone information.

PlainTime

The PlainTime in CADL map's to localTime type in morphir, defined as basic time without a timezone.