# Enumerative Type

Enum types generated by Set.
Enum types can be used as-is with type specifications, but further methods can be defined by classifying them into classes or defining patches.

A partially typed system with an enumerated type is called an enumerated partially typed.

```python
Bool = {True, False}
Status = {"ok", "error"}
```

Since `1..7` can be rewritten as `{1, 2, 3, 4, 5, 6, 7}`, so when element is finite, the Enum types essentially equivalent the Range types.

```python
Binary! = Class {0, 1}!.
    invert! ref! self =
        if! self == 0:
            do!:
                self.set! 1
            do!:
                self.set! 0

b = Binary!.new !0
b.invert!()
```

Incidentally, Erg's Enum types are a concept that encompasses enumerative types common in other languages.

```rust
// Rust
enum Status { Ok, Error }
```

```python
# Erg
Status = {"Ok", "Error"}
```

The difference with Rust is that it uses a structural subtype(SST).

```rust
// There is no relationship between Status and ExtraStatus.
enum Status { Ok, Error }
enum ExtraStatus { Ok, Error, Unknown }

// Methods can be implemented
impl Status {
    // ...
}
impl ExtraStatus {
    // ...
}
```

```python
# Status > ExtraStatus, and elements of Status can use methods of ExtraStatus.
Status = Trait {"Ok", "Error"}
    # ...
ExtraStatus = Trait {"Ok", "Error", "Unknown"}
    # ...
```

Methods can also be added by patching.

Use the `or` operator to explicitly indicate inclusion or to add a choice to an existing Enum type.

```python
ExtraStatus = Status or {"Unknown"}
```

An enumerated type in which all classes to which an element belongs are identical is called a homogenous enumerated type.

By default, a class whose requirement type is an homogeneous enumerated type can be treated as a subclass of the class to which the element belongs.

If you do not wish to do so, you can make it a wrapper class.

```python
Abc = Class {"A", "B", "C"}
Abc.new("A").is_uppercase()

OpaqueAbc = Class {inner = {"A", "B", "C"}}.
    new inner: {"A", "B", "C"} = Self.new {inner;}
OpaqueAbc.new("A").is_uppercase() # TypeError
```

<p align='center'>
    <a href='./10_interval.md'>Previous</a> | <a href='./12_refinement.md'>Next</a>
</p>