Now we will start talking about the points to note about the common handling operations for data types introduced in the previous article. However, before starting with detailed examples, I still want to re-list the names of the data types here so that we can easily follow the logic circuit and the relationship between the types (if any) –

`Float`

,`Int`

,`number`

– arithmetic values. For example:`10.01`

,`10`

, …`Bool`

– logical identifiers`True`

and`False`

`Char`

– single characters. For example:`'A'`

,`'z'`

, …`String`

– text strings. Example:`"Elm Language"`

`Record`

– describe records similar to`C struct`

and`JS Object`

`Tuple`

– concise description of records without field names`List`

– stores values of the same type in the form of an enumeration list

Ok.. let’s get started. To save time, we will interact with `Elm REPL`

like the previous article. However, you can create `module`

files to save the example code if you want.

1 2 3 | cd Documents && cd learn-elm elm repl |

## Arithmetic operations

`Package:`

`elm/core/Basics`

Not much different from `Imperative`

languages like `C`

or `JavaScript`

that we already know. `+`

, `-`

, `*`

, `/`

basic operations.

1 2 3 | 1.0 + 2.0 -- 3 : Float |

However, the first note is that `Elm`

does not support automatic conversion of the data type from `Int`

to `Float`

. The value returned by `round`

is of type `Int`

, and `1 : Int`

cannot be added directly to `2.0 : Float`

–

1 2 3 | (round 1.0) + 2.0 -- thông báo lỗi |

But `1 : number`

and `2.0 : Float`

are valid for such `+`

calculation. As for the reason, we will save it for the last item.

1 2 3 | 1 + 2.0 -- 3 : Float |

There is division to get the integer part with the `//`

symbol, I have never seen it.

1 2 3 | 9 // 2 -- 4 : Int |

The exponentiation uses the `^`

notation, which is different from `JS`

‘s `**`

.

1 2 3 | 2 ^ 10 -- 1024 : number |

In addition, other operations will be handled by `sub-program`

. For example, division with remainder `9 % 2`

in `JS`

–

1 2 3 | remainderBy 2 9 -- 1 : Int |

Taking the inverse of a number in `Elm`

will not use the `-`

operator. The reason is, I would like to save it for the next `Sub-Series`

. Here we just treat it as a special handling convention and use it like that.

1 2 3 | negate -9 -- 9 : number |

Absolute value –

1 2 3 4 5 6 | abs 10.01 -- 10.01 : Float abs -10.01 -- 10.01 : Float |

Square root of 2 –

1 2 3 | sqrt 81 -- 9 : Float |

Round the value to the nearest boundary –

1 2 3 4 5 6 | round 10.01 -- 10 : Int round 1.9 -- 2 : Int |

Round up and down –

1 2 3 4 5 6 | ceiling 9.5 -- 10 : Int floor 9.5 -- 9 : Int |

Decreasing to origin 0 –

1 2 3 4 5 6 | truncate 9.8 -- 9 : Int truncate -9.8 -- -9 : Int |

Checks the `NaN`

of a value obtained from an implementation that returns type `Float`

–

1 2 3 4 | isNaN (0/0) -- True isNaN (sqrt -1) -- True : Bool isNaN 1 -- False : Bool |

Division by `0/0`

and taking the square root of `-1`

cannot give an arithmetically significant result, so we get the value `NaN`

. However, in the case below, the result is positive infinity. `Infinite`

is still of type `Float`

.

1 2 3 | isNaN (1/0) -- False : Bool |

and to check if a return value from a `Float`

type operation is `Infinite`

–

1 2 3 4 5 | isInfinite (0/0) -- False isInfinite (sqrt -1) -- False isInfinite (1/0) -- True isInfinite 1 -- False |

`NaN`

and `Infinite`

are fundamentally different: `NaN`

has no arithmetic meaning, and `Infinite`

is an arithmetic value.

## Logical calculations

The symbols `&&`

and `||`

used by `Elm`

with the same meaning as `C`

and `JS`

. However, negation, also known as the inverse of a `Bool`

value, is handled by the `not`

program, instead of the `!`

like `C`

and `JS`

.

1 2 3 4 5 6 | not True -- False : Bool not False -- True : Bool |

Comparative statements, most still use the notations as we know `==`

, `>`

, `<`

, `>=`

, `<=`

. The only symbol `!=`

in `C`

and `JS`

to check the identity of two values is different, replaced by `Elm`

by `/=`

.

1 2 3 4 5 6 | 1 /= 0.9 -- True : Bool 1 /= 1.0 -- False : Bool |

## Type Variable

Purely `Declarative`

languages are mostly built with one spirit in mind – very strong typing and strict `strong-typing`

. And here we have `Elm`

as one of them.

Specifically the error message like the `+`

calculation example between an `Int`

value and a `Float`

value that we saw at the beginning of the article. Although `Elm`

‘s `compiler`

already has enough information about the received values before performing the calculation, `Elm`

simply does not support automatic implicit type conversion in this case. And we will need to do the data type conversion in our code –

1 2 3 | (toFloat (round 1.0)) + 2.0 -- 3 : Float |

Oh but why does the calculation

`1 + 2.0`

have no error message?

The value `1`

returned by `round`

is typed `Int`

. The value `1`

that we write directly into our code file is untyped, so `Elm`

will treat it as a variable of type `number`

.

The concept of variable type `Type Variable`

, can be understood simply as any data type that the `compiler`

does not find explicit type information in the code. And will try to find a most suitable success processing logic when getting the actual value at code `runtime`

.

Precisely, a variable type `a`

is understood as a `Union`

type that includes all data types that the compiler collects in the definition code of the entire `project`

program. However, `Elm`

also generates a few `Type Variable`

with more limited possibilities than `a`

. That is –

`number`

– is an arithmetic value; So it can be`Float`

or`Int`

.`comparable`

– is a value that can be compared by the`compare`

program; Includes`Int`

,`Float`

,`Char`

,`String`

, and`List/Tupple`

of those types.`appendable`

– is a value that can perform content concatenation operations; So it could be a`String`

or a`List`

.`compappend`

– is a value that is both`comparable`

and`appendable`

.

Thus, when the compiler reads the calculation `1 + 2.0`

, the value `2.0`

already has enough clear type information to be `Float`

due to the decimal point `.`

; The value `1`

does not have specific type information, so it will be `number`

. The most suitable success logic is `Float + Float`

and we have the compiled logic as `1.0 + 2.0`

. The calculation is done and there is no error message.

## comparable

By the way, after introducing the concept of `Type Variable`

variable type, we have some predefined types as listed above. The `number`

we just used to illustrate the example above, and among the remaining types, here we have enough knowledge to talk about `comparable`

.

A value of type

`comparable`

can be used in a comparison operation using the`compare`

program.

Here we need to pay a little attention to avoid confusion. The logical operations `>`

, `<`

, `==`

, `/=`

, etc.. that return `Bool`

values are used to test a comparison statement. In other words, to test an evaluation. And such a `kiểm tra`

operation will have a slightly different meaning from the `so sánh`

`compare`

that we just talked about above.

A test `a == b`

will give the answer to the question: ” `a`

is equal to `b`

. True or False? If `đúng`

, choose `True`

, and if `sai`

, choose `False`

. !”

1 2 3 | 1 == 0.9 -- False : Bool |

And a `compare ab`

comparison, on the other hand, will give the answer to the question: “What is `a`

vs `b`

? Equal to `EQ`

? Or less than `LT`

? Or greater than `GT`

? Answer immediately and always !”

1 2 3 | compare 1 0.9 -- GT : Order |

The result of a `so sánh`

, then, of course can also be used to navigate the operating logic of the code we build. And `Elm`

also has some basic, very useful programs that use these `Order`

values.

1 2 3 4 5 6 | -- max : comparable -> comparable -> comparable max 1 0.9 -- min : comparable -> comparable -> comparable min "abc" "xyz" |

About how the two strings `"abc"`

and `"xyz"`

are `compare`

with logic, we will save it for the next article.

(unpublished) [Declarative Programming + Elm] Lesson 5 – String & List