DAY 12
0
Software Development

## Algebraic Data Type

Algebra ，也就是代數，大家國小都學過，可以由簡單的加法與乘法組合而成，在 Category theory 中，也有著這樣的概念，甚至可以將這些概念應用在我們平常使用的 Type System 當中，今天來介紹其中的 sum type 跟 product type 吧。

# Sum type

``````val a: Boolean = true
-----------------------
val a: Boolean = false
``````

``````enum Light {
RED, YELLOW, GREEN
}

val l: Light = Light.RED
-------------------------
val l: Light = Light.YELLOW
------------------------
val l: Light = Light.GREEN
``````

``````val maybe: Maybe<Light> = Maybe.just(Light.RED)
-------------------
val maybe: Maybe<Light> = Maybe.just(Light.YELLOW)
-------------------
val maybe: Maybe<Light> = Maybe.just(Light.GREEN)
-------------------
val maybe: Maybe<Light> = Maybe.None()
``````

3 + 1 = 4 ，總共 4 種，依此類推， Maybe 就會是 `2 + 1 = 3` 總共 3 種。到這邊應該已經發現到一個規律了，不管 Maybe 裡面的 Type 是什麼，所產生出有可能的值會是原本的 Type 再加上 1。接下來，再來看看更複雜的例子，這邊介紹一個新的容器： Either。

Either 包含了兩種 Type，先暫定這兩個 Type 為 A 跟 B，而 A 跟 B 不會一起存在在同一個容器裡，有 A 就沒有 B，有 B 就沒有 A，以下是 Either 的實作：

``````sealed class Either<A, B>() {
class Left<A, B>(val value: A): Either<A, B>()
class Right<A, B>(val value: B): Either<A, B>()
}
``````

``````// Left 的建構式
val a: Either<Boolean, Light> = Either.Left(true)
// Right 的建構式
val b: Either<Boolean, Light> = Either.Right(Light.RED)
``````

``````Either<Boolean, Boolean> => 2 + 2 = 4
Either<Boolean, Unit>    => 2 + 1 = 3
Either<Unit, Byte>       => 1 + 256 = 257
Maybe<Boolean>           => 2 + 1 = 3
Maybe<Unit>              => 1 + 1 = 2
``````

# Product Type

``````val a: Pair<Boolean, Light> = true to Light.RED
-----------------------
val a: Pair<Boolean, Light> = true to Light.YELLOW
-----------------------
val a: Pair<Boolean, Light> = true to Light.GREEN
-----------------------
val a: Pair<Boolean, Light> = false to Light.RED
-----------------------
val a: Pair<Boolean, Light> = false to Light.YELLOW
-----------------------
val a: Pair<Boolean, Light> = false to Light.GREEN
``````

``````val a: Pair<Pair<Boolean, Light>, Byte> = (true to Light.RED) to 3
``````

``````data class Point(val x: Byte, val y: Byte)
``````

``````data class Position(val point: Point, val z: Byte) //256 * 256 * 256

// 可以發現到在 Pair 當中使用 Unit 是沒什麼意義的
Pair<Unit, Light>                             => 1 * 3 = 3
Tuple<Boolean, Byte, Light>                   => 2 * 256 * 3
``````