Skip to content

Commit

Permalink
Fix misexplanation of haskell's bottom type
Browse files Browse the repository at this point in the history
  • Loading branch information
Renegatto authored Jul 4, 2023
1 parent 0cd165e commit b25b46d
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions TypeTheory/NeverType.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
### Базовый пример

Например, у нас есть функция `exit`, что завершает исполнения нашей программы,
то есть функция никогда не завершиться! Вот реальная сигнатура `std::process::exit`
то есть функция никогда не завершится! Вот реальная сигнатура `std::process::exit`
из стандартной библиотеке Rust[^neverust]'а:
```rust
pub fn exit(code: i32) -> !
Expand All @@ -27,19 +27,25 @@ fn main() -> Result<!, ExitCode> {

## Альтернативы

В ML языках (например Haskell) так таковой never-тип не используется, сигнатура
той же функции `exit` в стандартной библиотеке Haskell'я выглядит так:
В Haskell в качестве never-типа используется `Void`, определенный как тип без конструктора:
```hs
data Void
```
Язык также поддерживает создание пользовательских пустых типов.
Стоит заметить, что в присутствии побочных эффектов нетерминированный терм не обязательно является пустым.
Так, например, сигнатура функции `exit` в стандартной библиотеке Haskell'я выглядит так:
```haskell
exitWith :: ExitCode -> IO a
```
* `a` - переменная типа

Здесь используется return-type полиморфизм, что с точки зрения типов будет иметь
похожий эффект как и never-тип.
```haskell
isOneOrDie :: Int -> IO String
isOneOrDie 1 = pure "ok"
isOneOrDie _ = die "💀"
За счет того, что этот терм в действительности не является пустым.

Однако, результат вычисления этого терма с побочными эффектами является пустым.
То есть ни одна программа, использующая результат вычисления этого терма никогда не будет выполнена.
Здесь, вместо `Void` используется аналогичный с точки зрения теории типов пустой тип - `forall a. a`.
Доказать, что он пуст несложно. Для этого достаточно подставить `Void` вместо переменной типа `a`:
```hs
exitWith @Void :: ExitCode -> IO Void
```

## Ссылки
Expand Down

0 comments on commit b25b46d

Please sign in to comment.