# Infinite Type

Infinite type sounds not good since we have no idea how much space would it take. Consider this:

```Prelude> let x = Nothing
Prelude> let x = Just x

<interactive>:2:9: error:
• Occurs check: cannot construct the infinite type: a ~ Maybe a
• In the expression: Just x
In an equation for ‘x’: x = Just x
• Relevant bindings include x :: a (bound at <interactive>:2:5)
```

At here, the type of `x` was `Maybe a` after the first command; into the second command, it became `Maybe Maybe Maybe <... infinite Maybe>` so we would never know when can we construct the type. So semantic checker or type checker would invent a rule call occurs check. In this case, `x` has a type `Maybe a` at the first step, into the second step it tries to construct a new type `Maybe Maybe a` and unify `Maybe a` with `Maybe Maybe a`, that means found an infinite type definition and it would reject such program.

But thought again, do we really didn't want infinite type? Or we are only didn't want the infinite construction? I thought the answer is we are trying to prevent infinite construction which we have no idea how big it's.

So let's dig into mud with curiosity, consider the following program(syntax is pesudo language):

```class Option[T]
// <: represents inherit/subtype
// and I'm comment
class Some[T](value: T) <: Option[T]
// ? explicit tell compiler it's a fresh free variable type
class None <: Option[?]
```

We can to pattern matching for everytime we want to do operations on `Option[T]`, like:

```foo(x: Option[int], y: Option[int]): Option[int] {
match (x, y) {
(Some(lv), Some(rv)) => return Some(lv + rv)
_ => return None
}
}
```

It's really annoying and makes us upset. So we invent infinite definition. Wait! You say we cannot measure how big the infinite type was! Yes, but what we are going to do is have an infinite definition for any construction, but we still only allow the finite construction.

I know that's confusing, so we start a trivial example, at the previous example we have to repackage the result of the operation back into `Option[T]`, we want to directly do operations on `Option[T]`, first take a look at the abstraction of additional:

```// +(int, int): int means int implements trait Add
+(self, self): self;
}
+(int, int): int;
}
```

To make `Option[T] + Option[T]` be possible, we need to make `Option[T]` implements `Add`, so first is we need the ability to reimplement a more special version than `Option[T]` for `Add`, this is because we don't want to change `Option[T]` definition all the time, and this is extendable by users' `trait`. And a more important reason is if `T` is not a subtype of `Add`, which means it's not addable, `Option[T]` should not be able addable either. So consider this definition:

```class Option[T <: Add] <: Add {
+(x: Option[T], y: Option[T]): Option[T] {
match (x, y) {
(Some(lv), Some(rv)) => return Some(lv + rv)
None => None
}
}
}
```

Notice why I say it's an infinite definition, this definition says `Option[T]` is a subtype of `Add` and only if `T` is a subtype of `Add`. Then consider this: `Option[Option[Option[T <: Add]]]`, it this type is a subtype of `Add`?

1. `T` is a subtype of `Add`
2. `Option[T]` is a subtype of `Add` because `T` is a subtype of `Add`
3. replace `Option[T]` with `T2` and back to step 1

Now we know, for any `Option[Option[...]]` type, if final `T` is a subtype of `Add`, it's a subtype of `Add`, and we can do the add-operation on it. So whatever user constructs how many of `Option`, we can use the same definition.

Of course, adding such a feature would be hard, where can we extend a type definition? How can we make sure users use it correctly? How to handle semantic conflict(e.g. several type-extend definitions implement the same `trait`)? But I still thought it's quite interesting and worth to write something about this. Thanks for the read.

Date: 2019-12-08 Sun 00:00