這是 ECMAScript 的老梗,但為什麼 Ramda 的 map() 就沒事呢 ?
Version
macOS Catalina 10.15.2
VS Code 1.40.2
Quokka 1.0.259
ECMAScript 2015
Ramda 0.26.1
map()
import { map } from 'ramda'
let data = ['1', '7', '11']
data.map(parseInt) // ?
map(parseInt)(data) // ?
同樣是將 parseInt() 傳進 map(),但 ECMAScript 的 map() 與 Ramda 的 map() 竟然結果不同 ?

ECMAScript
Array.prototype.map()
arr.map(function callback( currentValue[, index[, array]]) { // return element for new_array }[, thisArg])
將 array 轉換成新 array
ECMAScript 的 callback 會回傳 3 個 argument:
currentValue:目前 element 值index:目前 index 值array:完整 array
因此 map(parseInt) 依次會如下執行:
parseInt('1', 0, ['1', '7', '11']) // ?
parseInt('7', 1, ['1', '7', '11']) // ?
parseInt('11', 2, ['1', '7', '11']) // ?
已經可以發現 parseInt() 結果已經不如預期。

parseInt(string [, radix])
將 string 轉換成 int
其中第二個 argument 為 radix:
0:自動改為101:回傳NaN2~36:radix 合理值37以上:回傳NaN
因此 parseInt('1', 0) 為 10,parseInt('7', 1) 為 NaN,而 parseInt('11', 2) 為 3。
至於第三個 argument 會自動忽略。
Ramda
map()
Functor f => (a → b) → f a → f b
將 array 轉換成新 array
重點在於 map() 的 callback 只有 (a -> b),因此 parseInt() 的第二個 argument 為 undefined,所以 radix 為 10,結果如預期沒有任何意外。
parseInt('1') // ?
parseInt('7') // ?
parseInt('11') // ?
parseInt() 如預期結果。

Conclusion
- 由於 ECMAScript
map()的 callback 有 3 個 argument,都傳給parseInt()造成不可預期結果;但 Ramda 的 callback 只有 1 個 argument,因此如預期 radix 為10轉成 int
Reference
Eric Tong, Whe [‘1’, ‘7’, ‘11’].map(parseInt) return [1, NaN, 3] in JavaScript