DAY 11
1
Software Development

# Functor definition

Functor 的其中一個特性是保持結構的完整，如果在原本的 Category 中只有一個 object，經過 Functor 的轉換之後，不可能會出現兩個以上的 object，也就是一對一的對應關係，不會讓結構扭曲，擴大，或縮小。

``````val a: Int = 3
val Fa: Int? = 3
val b: String = "3"
val Fb: String? = "3"
val f: (Int) -> String = { it.toString }
val Ff: (Int?) -> String? = { it?.toString }
``````

## Identity and Associativity

Functor 也應該符合單位元與結合律這兩個特性，對於原本的 Category 來說是 Identity function 的話，經過 functor 的轉換，在另一個 Category 也應該要是 identity function ，不然這就不會是個一對一的對應關係了，而是有可能多對一。另一方面，結合律也會維持不變，不會到另一個 Category 時，結合律就消失了。

# Maybe Functor

``````sealed class Maybe<T>{
class Some<T>(val value: T): Maybe<T>()
class None<T> : Maybe<T>()

fun <R> map(transform: (T) -> R): Maybe<R> {
return when(this) {
is Some -> Some(transform(value))
is None -> None()
}
}

companion object {
fun <T> just(value: T?): Maybe<T> {
return if (value == null) {
None()
} else {
Some(value)
}
}
}
}
``````

``````fun foo() {
val a: String? = null
val b: String? = "not null"

// None
val maybeA = Maybe.just(a)
// Some("not null")
val maybeB = Maybe.just(b)
}
``````

``````    // None
val textLengthA = maybeA.map { it.length }
// Some(8)
val textLengthB = maybeB.map { it.length }
``````

``````val extras = intent.extras

if (extras != null) {
val user = extras.getParceable("User") as User?
if (user != null) {
// 沒完沒了啊～～
}
}
}
``````

``````val address = Maybe.just(intent.extras)
.mapNullable { extras.getParceable("User") as User? }

address.fold(somefun = {...}, nonefun = {...})
``````

``````fun <R> mapNullable(transform: (T) -> R?): Maybe<R> {
return when(this) {
is Some -> {
val result = transform(value)
if (result == null) {
None()
} else {
Some(result)
}
}
is None -> None()
}
}
``````