欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PureScript與JavaScript中equality設(shè)計(jì)的使用對(duì)比分析

 更新時(shí)間:2023年11月08日 11:23:23   作者:題葉  
這篇文章主要為大家介紹了PureScript中的equality與JavaScript中的equality設(shè)計(jì)對(duì)比分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

從 PureScript 的角度反過(guò)來(lái)看, JavaScript 的好多概念還是比較模糊的.

前幾天群里看到討論 js 的 equality 的事情, 我就覺得 js 設(shè)計(jì)挺不清晰的.

js 里用 === 的話, 遇到

  • literals 和 null/undefined, 按照 value 進(jìn)行判斷(我不懂 NaN...)
  • Array, Object, 按照引用進(jìn)行判斷

但是作為 calcit-js 作者, 我想說(shuō), 這些不是數(shù)據(jù)本身 equality 的性質(zhì),解釋器當(dāng)中的語(yǔ)義, 完全是編程語(yǔ)言作者設(shè)計(jì)了暴露出來(lái)的接口,判斷引用來(lái)判斷是否相等, 運(yùn)行指令的時(shí)候會(huì)非常快, 但這不是我們業(yè)務(wù)當(dāng)中想要的語(yǔ)義.

我們?cè)跇I(yè)務(wù)當(dāng)中遇到數(shù)據(jù)要判斷是否"等價(jià)", 就需要按照值進(jìn)行判斷,當(dāng)我們用組合而成的數(shù)據(jù)結(jié)構(gòu)來(lái)表示數(shù)據(jù)的時(shí)候, 就需要根據(jù)結(jié)構(gòu)遞歸進(jìn)行判斷.

而 js 的 === 只是一個(gè)封裝暴露平臺(tái)底層能力的功能, 沒有往函數(shù)式編程做.

PureScript 當(dāng)中怎么判斷是否相等的

開始之前, 需要定義一個(gè)數(shù)據(jù)類型, 比如我直接叫做 Cirru,

data Cirru = CirruString String | CirruList (Array String)

這段代碼的含義是我定一個(gè)了一個(gè)類型 Cirru, 有兩種情況,

  • 一個(gè)是通過(guò)數(shù)據(jù)構(gòu)造器 CirruString "a" 構(gòu)造的第一種可能,
  • 一個(gè)是通過(guò)數(shù)據(jù)構(gòu)造器 CirruList ["b"] 構(gòu)造的第二種可能,

用兩個(gè)簡(jiǎn)單的數(shù)據(jù)進(jìn)行判斷

比方說(shuō)我們用兩個(gè)簡(jiǎn)單的數(shù)據(jù)進(jìn)行判斷的時(shí)候,

(CirruString "A") == (CirruString "B")

PureScript 類型檢查會(huì)報(bào)錯(cuò), 認(rèn)為找不到 Cirru 這個(gè)類型怎么處理的辦法,

No type class instance was found for
    Data.Eq.Eq Cirru
while applying a function eq
  of type Eq t0 => t0 -> t0 -> Boolean
  to argument CirruString "A"
while inferring the type of eq (CirruString "A")
in value declaration main
where t0 is an unknown type

因?yàn)槭呛瘮?shù)式編程, 它的內(nèi)部其實(shí)會(huì)把 == 轉(zhuǎn)換回到一個(gè)函數(shù) eq,

eq (CirruString "A") (CirruString "B")

通過(guò)函數(shù)進(jìn)行判斷, 但是 eq 在 type class 當(dāng)中只是通用的定義,

eq :: a -> a -> Boolean

https://pursuit.purescript.or...

其中 a 是某個(gè)類型, 但他并不知道 Cirru 對(duì)應(yīng)的 eq, 就得到了上邊的報(bào)錯(cuò),

No type class instance was found for
    Data.Eq.Eq Cirru
while applying a function eq
  of type Eq t0 => t0 -> t0 -> Boolean
  to argument CirruString "A"
while inferring the type of eq (CirruString "A")
in value declaration main
where t0 is an unknown type

PureScript derive 集成內(nèi)置的實(shí)現(xiàn)

作為 js 程序員, 當(dāng)然你也會(huì)有一些常見的處理辦法, "直接遞歸判斷不就好了?",那么 PureScript 也提供了這樣的一種方式, 你可以通過(guò) derive 集成內(nèi)置的一個(gè)實(shí)現(xiàn),

derive instance cirruEq :: Eq Cirru

這樣當(dāng)你再去判斷的時(shí)候, 就能得到期望的結(jié)果了,

main = do
  log $ show $ (CirruString "A") == (CirruString "B")
  log $ show $ eq (CirruString "A") (CirruString "B")

  log $ show $ (CirruString "A") == (CirruString "A")
  log $ show $ eq (CirruString "A") (CirruString "A")
  log $ show $ (CirruList ["A"]) == (CirruList ["A"])

=>> spago run
[info] Build succeeded.
false
false
true
true
true

或者, 另一種更常見的方式是你自己去定義 eq 對(duì)應(yīng)對(duì)的實(shí)現(xiàn)是什么樣?

比如這樣的代碼, 就通過(guò)遞歸, 把判斷變成內(nèi)部的數(shù)據(jù)的判斷,

instance cirruEq :: Eq Cirru where
  eq (CirruString x) (CirruString y) = x == y
  eq (CirruList x) (CirruList y) = x == y
  eq _ _ = false

總結(jié)

最后 eq _ _ 表示剩下的其他的沒覆蓋到的可能性.

從這個(gè)代碼的原理上說(shuō), 你完全可以自己定義數(shù)據(jù)是否相等的規(guī)則,即便你把 (CirruString "A") == (CirruList ["A"]) 定義相等, 也能寫出來(lái)

instance cirruEq :: Eq Cirru where
  eq (CirruString x) (CirruString y) = x == y
  eq (CirruList x) (CirruList y) = x == y
  -- 看這行
  eq (CirruString x) (CirruList ys) = if (length ys) == 1 then (Just x) == (head ys) else false
  eq _ _ = false

你可以簡(jiǎn)單認(rèn)為是 type class 先定義出來(lái)了一套接口, 其中有 eq,然后其他類型定義好后, 也需要定義對(duì)應(yīng)的 eq 的實(shí)現(xiàn), 然后才能用于計(jì)算.

JavaScript 作為腳本語(yǔ)言, 把其中一種特例, 硬編碼在語(yǔ)言解釋器上了.

你要找準(zhǔn)確的理解, 就要回到 PureScript 這樣的定義當(dāng)中去.

可以看到, 在語(yǔ)義層面我們不會(huì)去觸碰"內(nèi)存引用的地址是否相等"的判斷,當(dāng)你在 PureScript 用 FFI 的方式去調(diào)用 js, 可能是會(huì)碰到,但是這些硬件相關(guān)的實(shí)現(xiàn)細(xì)節(jié), 是盡量被封裝到語(yǔ)言實(shí)現(xiàn)的底層當(dāng)中去隱藏起來(lái)的.

本文是我的一些學(xué)習(xí)筆記和新得, 使用的術(shù)語(yǔ)不大準(zhǔn)確,如果你需要更精確的概念, 可能需要翻一下 Haskell 相關(guān)文檔,更多關(guān)于PureScript equality對(duì)比JavaScript 的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • TypeScript使用strictnullcheck實(shí)戰(zhàn)解析

    TypeScript使用strictnullcheck實(shí)戰(zhàn)解析

    這篇文章主要為大家介紹了TypeScript使用strictnullcheck實(shí)戰(zhàn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • TypeScript?泛型接口具體使用實(shí)戰(zhàn)

    TypeScript?泛型接口具體使用實(shí)戰(zhàn)

    這篇文章主要為大家介紹了TypeScript?泛型接口具體使用實(shí)戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • TypeScript 交叉類型使用方法示例總結(jié)

    TypeScript 交叉類型使用方法示例總結(jié)

    這篇文章主要為大家介紹了TypeScript 交叉類型使用方法示例總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • TypeScript?類型級(jí)別示例介紹

    TypeScript?類型級(jí)別示例介紹

    這篇文章主要為大家介紹了TypeScript?類型級(jí)別示例介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Typescript編碼規(guī)范ESLint和Prettier使用示例詳解

    Typescript編碼規(guī)范ESLint和Prettier使用示例詳解

    這篇文章主要介紹了Typescript編碼規(guī)范ESLint和Prettier使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • TypeScript之Generics泛型類型學(xué)習(xí)

    TypeScript之Generics泛型類型學(xué)習(xí)

    這篇文章主要為大家介紹了TypeScript之Generics泛型類型學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • TypeScript保姆級(jí)基礎(chǔ)教程

    TypeScript保姆級(jí)基礎(chǔ)教程

    這篇文章主要為大家介紹了TypeScript保姆級(jí)基礎(chǔ)教程示例詳解,主要為大家介紹了typescript的類型,函數(shù),對(duì)象,接口等基礎(chǔ)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-07-07
  • d3-scale d3-scaleTime使用示例詳解

    d3-scale d3-scaleTime使用示例詳解

    這篇文章主要為大家介紹了d3-scale d3-scaleTime使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Three.js?粗糙度貼圖與金屬度貼圖使用介紹

    Three.js?粗糙度貼圖與金屬度貼圖使用介紹

    這篇文章主要為大家介紹了Three.js?粗糙度貼圖與金屬度貼圖使用介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • TypeScript條件類型示例全面講解

    TypeScript條件類型示例全面講解

    這篇文章主要為大家介紹了TypeScript條件類型示例的全面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07

最新評(píng)論