- Вывод типов (type inference)
- в программировании, у компилятора есть возможность самому логически вывести тип значения у выражения.

```go
func main() {
var x float32 = 123.78
y := 23
fmt.Printf("%T", y + x)
} // invalid operation: y + × (mismatched types int and float32)
```
```go
func main() {
var x float32 = 123.78
y := 23 + x
fmt.Printf("%T", y)
} // float32
```
```haskell
map f [] = []
map f (x:xs) = f x : map f xs
-- map :: _ -> _ -> _
-- map :: _ -> [_] -> _
-- map :: _ -> [_] -> [_]
-- map :: (_ -> _) -> [_] -> [_]
-- map :: forall a.
-- (a -> _) -> [a] -> [_]
-- map :: forall a b.
-- (a -> b) -> [a] -> [b]
```
----
### Тотальность функций
```text
number
integer fraction exponent
integer
digit
onenine digits
'-' digit
'-' onenine digits
digits
digit
digit digits
digit
'0'
onenine
```
```text
onenine
'1' . '9'
fraction
""
'.' digits
exponent
""
'E' sign digits
'e' sign digits
```
Что такое number?
----
### Что такое number в JSON?
`number` может быть: `short`, `int`, `long`, `big-int`, `float`, `double`
### Контекст
- JavaScript — старая экосистема, разработанная для автоматизации веба "на коленке".
- Следствие: работа с `number` как с `long` в большинстве решений.
- Haskell — язык, сделанный любителями и профессионалами от математики.
- Следствие 1: есть `Integer` без ограничения диапазона значений.
- Следствие 2: библиотека Aeson (стандарт для работы с JSON) интерпретирует `number` как `Integer`.
- Crypto & Blockchain mess — активное использование ключей.
- Следствие: числа в 256 бит не предел.
----
#### Проблема
- Передача JSON из Haskell в веб.
- Сериализация `Integer` в `number` формирует очень длинное число, которое парсится в `long`.
- Hash перестаёт совпадать.
#### Решение
- предобработка текста JSON с заменой всех больших `number` на специальную строку;
- постобработка структуры с JSON с возвращением всех `number` к истинным значениям.
---
### Behavior Indirection: Polymorphism
1. **Универсальный** (universal)
1. Параметрический (parametric) — обощённые структуры и код, любые данные внутри.
1. Наследование (subtyping) — ООП, использование наслед.
1. **Специальный** (ad-hoc)
1. Перегрузка (overloading)
- Ограниченный (bounded)
- Перегрузка имён функций (func. names overloading)
1. Приведение типов (coercion)

Частично заимствовано тут:
- [Haskell Beginners 2022.
Lecture 3: Typeclasses](https://slides.com/haskellbeginners2022/lecture-3)
- [Душкин Роман
Полиморфизм в языке Haskell](https://fprog.ru/2009/issue3/roman-dushkin-haskell-polymorphism/)
---
### Universal. Один код, разные данные
```haskell
filterInt :: (Int -> Bool) -> [Int] -> [Int]
filterInt _ [] = []
filterInt p (x:xs)
| p x = x : filterInt p xs
| otherwise = filterInt p xs
```
```haskell
filterChar :: (Char -> Bool) -> [Char] -> [Char]
filterChar _ [] = []
filterChar p (x:xs)
| p x = x : filterChar p xs
| otherwise = filterChar p xs
```
----
#### Динамика
```python
lst = [
{'x': 1, 'y': 3, 'z': 7},
{'x': 2, 'y': 2, 'z': 8},
{'x': 3, 'y': 1, 'z': 1},
]
sorted(lst, key=lambda e: e['x'])
# => [ {'x': 1, 'y': 3, 'z': 7}
# , {'x': 2, 'y': 2, 'z': 8}
# , {'x': 3, 'y': 1, 'z': 1}]
sorted(lst, key=lambda e: e['y'])
# => [ {'x': 3, 'y': 1, 'z': 1}
# , {'x': 2, 'y': 2, 'z': 8}
# , {'x': 1, 'y': 3, 'z': 7}]
```
1. The first element of a pair
1. Reversing a list
1. List length
1. Taking 5 elements from a list
1. Function composition
1. etc.
----
#### Параметрический (parametric) полиморфизм /1
```haskell
filter :: forall a. (a -> Bool) -> [a] -> [a]
filter _ [] = []
filter p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
-- TypeApplications: @
filter @Int :: (Int -> Bool) -> [Int] -> [Int]
filter @String :: (String -> Bool) -> [String] -> [String]
```
----
#### Параметрический (parametric) полиморфизм /2
```haskell
data Maybe a = Just a | Nothing
type MaybeInt = Maybe Int
```
```java
public class Box