點燈坊

失くすものさえない今が強くなるチャンスよ

如何以 Point-free 處理 Binary Function ?

Sam Xiao's Avatar 2021-04-22

Point-free 天生適合 Unary Function,但實務上還是常常遇到 Binary Function 甚至 Ternary Function,對於這類 Function 該如何在 Vue 3 搭配 Point-free 呢 ?

Version

Vue 3.0.11

Point-free

binary000

按下 = 會計算兩數相加。

<template lang='pug'>
input(v-model='x')/
span +
input(v-model='y')/
button(@click='onClick') =
span {{ sum }}
</template>

<script setup>
import { ref, unref } from 'vue'
import { write } from 'vue3-fp'
import { pipe, apply } from 'ramda'

let x = ref('')
let y = ref('')
let sum = ref('')

let add = (x, y) => x + y

let onClick = pipe(
  () => [+unref(x), +unref(y)],
  apply(add),
  write(sum)
)
</script>

18 行

let add = (x, y) => x + y

add() 是典型 binary function,這對 Point-free 並不友善,但實務上還是常遇到這類 function。

20 行

let onClick = pipe(
  () => [+unref(x), +unref(y)],
  apply(add),
  write(sum)
)

使用 pipe() 組合出 onClick()

  • () => [+unref(x), +unref(y)]:將 xy 以 Array 形式回傳,這是本文關鍵
  • apply(add):將 add() 轉成 unary function 適合 Point-free
  • write(sum):將結果寫入 sum state

直覺會想使用 always([+unref(x), +unref(x)])list(unref(x), unref(y)),但無奈 Vue 3 對 always()list() 這類 higher order function 會喪失 reactive,因此只能使用 arrow function

Conclusion

  • 使用 apply() 是關鍵,他可將 binary function 甚至 ternary function 轉成 unary function,然後再將原本 argument 改用 Array 提供

Reference

Ramda, apply()