DAY 2
1
Software Development

# Function composition

``````fun addOne(a: Int) = a + 1
fun timesTwo(a: Int) = a * 2
``````

``````// (3*2) + 1
val result = addOne(timesTwo(3))
println(result)
``````

``````val addOne = { x: Int -> x + 1}
val timesTwo = { x: Int -> x * 2}

println(result)
``````

``````// 非常直覺
fun addOne(a: Int) = a + 1
fun timesTwo(a: Int) = a * 2
fun composeFun(a: Int) = addOne(timesTwo(a))

// 糟了！這要怎麼組合？
val addOne = { x: Int -> x + 1}
val timesTwo = { x: Int -> x * 2}
val composeFun = addOne(timesTwo(x))   //x 從哪裡來？
``````

# Lazy execution

``````val composeFun: (Int) -> Int = { x: Int -> ??? }
``````

``````val composeFun: (Int) -> Int = { x: Int -> addOne(timesTwo(x)) }
``````

# Generalization

``````val anotherFun = addOne compose timesTwo
``````

``````// 也別忘了 extension function
infix fun ???.compose(anotherFun: ??): ??
``````

``````infix fun ((Int) -> Int).compose(anotherFun: (Int) -> Int): (Int) -> Int {
return ???
}
``````

``````infix fun ((Int) -> Int).compose(anotherFun: (Int) -> Int): (Int) -> Int {
return { x: Int ->
???
}
}
``````

``````infix fun ((Int) -> Int).compose(anotherFun: (Int) -> Int): (Int) -> Int {
return { x: Int ->
this(anotherFun(x))
}
}
``````

``````infix fun <T, Q, R> ((Q) -> R).compose(anotherFun: (T) -> Q): (T) -> R {
return { x: T ->
this(anotherFun(x))
}
}

val composeFun = addOne compose timesTwo
println(composeFun(4))      // 9
``````

``````val composeFun = addOne pipe timesTwo pipe addOne
println(composeFun(4))      // (4 + 1) * 2 + 1 = 11
``````

# 結語

### 1 則留言

1

iT邦新手 3 級 ‧ 2020-09-15 08:47:00

``````fun addOne(a: Int) = a + 1
fun timesTwo(a: Int) = a * 2
fun composeFun(a: Int) = addOne(timesTwo(a))
``````

``````val addOne = { x: Int -> x + 1}
val timesTwo = { x: Int -> x * 2}
val composeFun = (Int) -> Int = { x: Int -> addOne(timesTwo(x)) }
``````

``````function addOne(a) {
return a + 1;
}

function timesTwo(a) {
return a * 2;
}

const r1 = addOne(timesTwo(3)); // 馬上運算 timesTwo(3)，沒有 lazy

return f() + 1;
}

const r2 = callfAndAddOne(() => timesTwo(3));  // 延遲運算 timesTwo(3)
``````

``````function addOne(a) {
return a + 1;
}

function timesTwo(a) {
return a * 2;
}

function callfAndAddOne(f, x) {
return f(x) + 1;
}

const r2 = callfAndAddOne(x => timesTwo(x), 3);  // 延遲運算 timesTwo
console.log(r2);
``````

``````function addOne(a) {
return a + 1;
}

function timesTwo(a) {
return a * 2;
}

const callfAndAddOne = f => x => f(x) + 1;

const r2 = callfAndAddOne(x => timesTwo(x))(3);
console.log(r2);
``````

``````function addOne(a) {
return a + 1;
}

function timesTwo(a) {
return a * 2;
}

const composefAndAddOne = f => x => f(x) + 1;  // 通用化 AddOne 與 f 的 compose