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:
| Type | TypeSpec Type | Comment | |
|---|---|---|---|
| Basic Types | |||
Bool | boolean | ||
Int | int64 | ||
Float | float64 | ||
String | string | ||
Char | string | Not supported. Mapped to string | |
| Advanced Types | |||
Decimal | string | Not supported. Mapped to string | |
LocalDate | plainDate | ||
LocalTime | plainTime | ||
Month | string | ||
| Optional Types | |||
Maybe a | a| null | ||
{ foo: Maybe Float, bar: String } | { foo ?: float64, bar: string } | Optional Fields are expressed using the ?: syntax | |
| Collection Types | |||
List A | Array<A> | ||
Set B | Array<B> | Not Supported. Mapped to Array | |
Dict A B | Array<[A,B]> | Not Supported. Mapped to Array | |
| Composite Types | |||
| - Tuple | (Int, String) | [int64, string] | |
| - Result | Result e v | ["Err", e] | ["Ok", v] | Expressed as tagged unions | 
| - Record | { foo: Int, bar: String } | { foo: int64, bar: string } | |
| - Union Types | Foo Int | Bar String | ["Foo", int64] | ["Bar, string] | |
| - No Constructor Args (Special Case) | Foo | Bar | Baz | Foo | Bar | Baz | Represented 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. 
maybeas a standalone type, is presented in cadl as a union of the type or null using the pipe|syntax.Elm:
type alias Foo =
Maybe IntTypeSpec:
alias Foo = int64 | nullmaybeas a field type in a record, is represented asoptional fieldin a model in TypeSpec usingoptional field?:syntax.Elm:
type alias FooBarBaz =
{ foo: Int
, bar: Float
, baz: Maybe String
}TypeSpec:
model FooBarBaz {
foo : int64;
bar : float;
baz ?: string
}In a Scenario where a field type is
maybeof anothermaybetype, it is represented as anoptional fieldof theuniontype.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
maybetype 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 Type | Morphir Type | Comment | |
|---|---|---|---|
| Namespaces | namespace Petstore | module PetStore exposing (...) | Namespaces in CADL map to Modules in Morphir | 
| Models | model Dog { name: string;  age: number} | type alias Dog = { name: string, age: int} | Models in CADL map to Records in Morphir | 
| Enums | enum 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:
- 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.