av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

Ramda哪些讓人困惑的函數(shù)簽名規(guī)則

(Applicative f, Traversable t) => (a → f a) → t (f a) → f (t a)

或者,某一些函數(shù)"奇怪"的用法:

創(chuàng)新互聯(lián)建站執(zhí)著的堅(jiān)持網(wǎng)站建設(shè),微信平臺(tái)小程序開發(fā);我們不會(huì)轉(zhuǎn)行,已經(jīng)持續(xù)穩(wěn)定運(yùn)營(yíng)10多年。專業(yè)的技術(shù),豐富的成功經(jīng)驗(yàn)和創(chuàng)作思維,提供一站式互聯(lián)網(wǎng)解決方案,以客戶的口碑塑造品牌,攜手廣大客戶,共同發(fā)展進(jìn)步。

// R.ap can also be used as S combinator // when only two functions are passed 
R.ap(R.concat, R.toUpper)('Ramda') //=> 'RamdaRAMDA'

這些"奇怪"的點(diǎn)背后投射著 Ramda "更深"一層的設(shè)計(jì)邏輯, 本文將會(huì)對(duì)此作出講解, 并闡述背后通用的函數(shù)式編程理論知識(shí)。

Ramda 為人熟知的一面?

Ramda 經(jīng)常被當(dāng)做 Lodash 的另外一個(gè)"更加FP"的替代庫(kù),相對(duì)于 Lodash,Ramda 的優(yōu)勢(shì)(之一)在于完備的柯里化與 data last 的設(shè)計(jì)帶來的便捷的管道式編程(pipe)。

舉一個(gè)簡(jiǎn)單的代碼對(duì)比示例:

  • Ramda:
const myFn = R.pipe (
R.fn1,
R.fn2 ('arg1', 'arg2'),
R.fn3 ('arg3'),
R.fn4
)
  • Lodash:
const myFn = (x, y) => {
const var1 = _.fn1 (x, y)
const var2 = _.fn2 (var1, 'arg1', 'arg2')
const var3 = _.fn3 (var2, 'arg3')
return _.fn4 (var3)
}

Ramda 類型簽名?

在 Ramda 的 API 文檔中, 類型簽名的語(yǔ)法有些"奇怪":

  • add: Number → Number → Number

我們結(jié)合 Ramda 的柯里化規(guī)則, 稍加推測(cè), 可以將這個(gè)函數(shù)轉(zhuǎn)換為TypeScript 的定義:

export function add(a: number, b: number): number;
export function add(a: number): (b: number) => number;

OK, 那為什么Ramda 的文檔不直接使用TypeScript 表達(dá)函數(shù)的類型呢? -- 因?yàn)楦雍?jiǎn)潔!

Ramda 文檔中的類型簽名使用的是Haskell 的語(yǔ)法, Haskell 作為一門純函數(shù)式編程語(yǔ)言, 可以很簡(jiǎn)潔地表達(dá)柯里化的語(yǔ)義, 相較之下, TypeScript 的表達(dá)方式就顯得比較臃腫。

當(dāng)然, 使用Haskell 的類型簽名的意義不僅于此, 讓我們?cè)倏纯雌渌?奇怪"的函數(shù)類型:

  • ap:
[a → b] → [a] → [b]
Apply f => f (a → b) → f a → f b
(r → a → b) → (r → a) → (r → b)

結(jié)合文檔中的demo:

R.ap([R.multiply(2), R.add(3)], [1,2,3]); //=> [2, 4, 6, 4, 5, 6]

R.ap([R.concat('tasty '), R.toUpper], ['pizza', 'salad']); //=> ["tasty pizza", "tasty salad", "PIZZA", "SALAD"]

// R.ap can also be used as S combinator
// when only two functions are passed
R.ap(R.concat, R.toUpper)('Ramda') //=> 'RamdaRAMDA'

[a → b] → [a] → [b]我們好理解, 就是笛卡爾積;

(r → a → b) → (r → a) → (r → b)我們也能理解, 就是兩個(gè)函數(shù)的串聯(lián);

Apply f => f (a → b) → f a → f b就有點(diǎn)難理解了, 語(yǔ)法上就有些陌生, 我們先將其翻譯成TypeScript 語(yǔ)法:

:), 好吧, 這段類型沒法簡(jiǎn)單地翻譯成TypeScript, 因?yàn)? TypeScript 不支持將 「類型構(gòu)造器」 作為類型參數(shù)!舉個(gè)例子:

type T = F;

報(bào)錯(cuò)信息如下:

Type 'F' is not generic.

在類型簽名中F?是一個(gè)類型構(gòu)造器, 既和Array一樣的 「返回類型的類型」, 然而, TypeScript 里根本無(wú)法聲明"一個(gè)類型參數(shù)為類型構(gòu)造器"。

正如示例中type T = F;?中, 我們無(wú)法告訴TypeScript, 這里的F?是一個(gè)類型構(gòu)造器, 所以當(dāng)將number?傳入F的時(shí)候, 就報(bào)錯(cuò)了。

OK, 我們假設(shè)TypeScript 支持聲明"一個(gè)類型參數(shù)為類型構(gòu)造器", 讓我們?cè)賮砜纯碅pply f => f (a → b) → f a → f b該怎么翻譯:

type AP = (f: F<((a: A) => B)>) => (fa: F) => F;

這里的F可以理解為一種 「上下文」, 這段類型簽名可以先簡(jiǎn)單地理解為:

將一個(gè)包裹在上下文中的「函數(shù)」取出, 再將另一個(gè)包裹在上下文中的「值」取出, 調(diào)用函數(shù)后, 將函數(shù)的返回值重新包裹進(jìn)上下文中并返回。

這里的 「上下文」 是一個(gè)泛指, 比如我們可以將其特異化(specialize)為 Promise :

type AP = (f: Promise<((a: A) => B)>) => (fa: Promise) => Promise;  
const ap: AP = (f) => fa => f.then(ff => fa.then(ff));

ap? 或說 Apply 作為函數(shù)式編程中的一種常見抽象, 有非常重要重要的學(xué)習(xí)意義, 但其抽象的解析超出本文范圍, 在這里我們只聚焦于「是什么」, 暫不考慮「為什么」。

那么, (r → a → b) → (r → a) → (r → b)與Apply f => f (a → b) → f a → f b是什么關(guān)系?

他們之間是同父異母的關(guān)系, (r → a → b) → (r → a) → (r → b)?是對(duì)Apply f => f (a → b) → f a → f b的特異化, 正如我們對(duì)Promise 做的那樣。

函數(shù)也可以是一個(gè) 「上下文」?

答案是可以的, 我們可以將一個(gè)一元函數(shù)a -> b?理解為"一個(gè)包裹在上下文中的b?, 只不過為了獲取這個(gè)b?, 需要先傳入一個(gè)a。

先看看 Haskell 對(duì)ap 的定義:

instance Applicative ((->) r) where
(<*>) f g x = f x (g x)

替換為TypeScript 的實(shí)現(xiàn), 我們將上面的Promise 的例子稍微修改下, 得出:

type F = (a: any) => A;

type AP = (f: F<((a: A) => B)>) => (fa: F
) => F;

const ap: AP = f => fa => {
return (r) => f(r)(fa(r));
}

同樣的, 我們得到Apply 特異化為Array 的實(shí)現(xiàn):

type AP = (f: Array<((a: A) => B)>) => (fa: Array) => Array;

const ap: AP = f => fa => {
return f.flatMap(ff => fa.map(ff));
};

綜上所述, 我們可以得出結(jié)論:

ap的類型簽名[a → b] → [a] → [b]和(r → a → b) → (r → a) → (r → b)是Apply f => f (a → b) → f a → f b的特異化。


新聞名稱:Ramda哪些讓人困惑的函數(shù)簽名規(guī)則
當(dāng)前鏈接:
http://uogjgqi.cn/article/dpdjdcj.html
掃二維碼與項(xiàng)目經(jīng)理溝通

我們?cè)谖⑿派?4小時(shí)期待你的聲音

解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流