點燈坊

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

ap() 與 seq() 之比較

Sam Xiao's Avatar 2020-11-22

ap()seq() 都是 S Combinator,但其 Signature 不同,因此使用時機也不太一樣。

Version

Vue 3.0.0
Ramda 0.27.1
Wink-fp 1.23.9

seq()

ap-seq000

data 只有單一 primitive,但同時有兩次 side effect。

<template>
  {{ data }}
</template>

<script setup>
import { pipe } from 'ramda'
import { seq, log } from 'wink-fp'
import { onMounted, ref } from 'vue'
import { read } from 'vue3-fp'

export let data = ref(1)

let multiEffect = pipe(
  seq(log, log)
)

let mount = pipe(
  read(data),
  multiEffect
)

onMounted(mount)

export default {
  name:'App'
}
</script>

11 行

export let data = ref(1)

data state 為單一 primitive。

13 行

let multiEffect = pipe(
  seq(log, log)
)

使用 seq() 同時對單一 primitive 有多次 side effect。

17 行

let mount = pipe(
  unwrap(data),
  multiEffect
)
  • 使用 read() 讀取 data state
  • 傳入 multiEffect()

ap()

ap-seq001

data 為 Array,雖然只有一次 side effect,但 Array 中每個 element 都值行過一次。

<template>
  {{ data }}
</template>

<script setup>
import { ap, pipe } from 'ramda'
import { log } from 'wink-fp'
import { onMounted, ref } from 'vue'
import { read } from 'vue3-fp'

export let data = ref([1, 2])

let multiEffect = pipe(
  ap([log])
)

let mount = pipe(
  read(data),
  multiEffect
)

onMounted(mount)

export default {
  name:'App'
}
</script>

11 行

export let data = ref([1, 2])

data state 為兩個 element 的 Array。

13 行

let multiEffect = pipe(
  ap([log])
)

使用 seq() 同時對 Array 中每個 element 都有 side effect。

其中 ap() 要求將 function 以 Array 傳入,因此也能傳入多個 side effect。

Conclusion

  • seq() 的 data 為單一 primitive;而 ap() 的 data 為 Array,因為 ap() 原本是用在 Apply container
  • seq() 可接受多個 side effect 為 variadic function;而 ap() 亦可接受多個 side effect,但 argument 為 Function Array
  • ap() 會對 Array 中每個 element 都執行一次 side effect,若有 m 個 element,且有 n 個 side effect,將執行 m * n 次 side effect

Reference

Ramda, ap()