在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

什么是高階類型啊?如何去定義高階類型呢

jf_wN0SrCdH ? 來源:碼小菜 ? 作者:碼小菜 ? 2022-11-07 10:20 ? 次閱讀

05ad3ac8-5de9-11ed-a3b6-dac502259ad0.jpg

Rust在類型系統級別上與Haskell,Scala有許多相似之處。

兩者都有類型(type),泛型類型(generic types),關聯類型(associated types)和特質/類型類(traits/type classes)(基本上是等效的)。

但是,Haskell有Rust缺乏的一個特性:高階類型(Higher Kinded Types), 也就是通常說的HKTs。

這不是Rust故意不添加,也不是Rust應該填補的一些差距。其實這是Rust的一個有意的設計。

結果就是,到沒有GATs出現時,某些代碼無法真正在Rust中實現。

以Haskell中的Functor為例。Functor其實是對類型上實現的map的一個更加抽象的實現,不關心具體類型的一個接口

比如,在Scala中,要實現一個map的Functor是這樣的:

importscala.language.higherKinds

traitFunctor[F[_]]{
defmap[A,B](fa:F[A])(f:A=>B):F[B]
}

如果你使用過Scala的集合api,這看起來應該非常相似。所有集合都可以使用map。

List(1,2,3).map(_+1)
//List(2,3,4)

你可能要問,什么是高階類型啊.你可以先理解為: 高階類型是類型的類型。這是什么意思呢? 我以Scala里面的代碼來說明一下。

scala>traitMyList[A]{
defhead:A
deftail:MyList[A]
}

然后用:k命令看下是什么類型:

scala>:k-vMyList
MyList'skindisF[A]
*->*
Thisisatypeconstructor:a1st-order-kindedtype.

MyList[String]類型是一個一階類型(1st-order-kinded type);任何MyList的類型都是由A參數化的,可以將MyList看作是一個類型函數,如A => MyList[A],因此給定一個類型A,我們可以創建一個新的類型MyList[A]。如果MyList是一階類型,那么什么是類型化類型呢?其實想想,什么是高階函數啊? 它不就是一個接受函數然后返回另外另一個函數的函數。同理可得,什么是高階類型呢? 它是由另一個類型參數化的類型。我再寫一個簡單的例子。

scala>traitFoo[F[_]]:k-vFoo
Foo'skindisX[F[A]]
(*->*)->*
Thisisatypeconstructorthattakestypeconstructor(s):ahigher-kindedtype.

這里的Foo就是一個高階類型。它是一個類型構造函數,參數也是一個類型構造函數。為了說清楚這點,我再寫一個例子.我寫一個trait,里面有一個leftFold的方法。

scala>traitFoldable[F[_]]{
|defleftFold[A,B](ob:F[A])(zero:B)(fn:(B,A)=>B):B
|}

然后呢,我再實現一個listFoldable, 這是最常見的吧。

scala>implicitvallistFoldable:Foldable[List]=newFoldable[List]{
|defleftFold[A,B](ob:List[A])(zero:B)(fn:(B,A)=>B):B={
|ob.foldLeft(zero)(fn)
|}
|}

上面我定義了一個適用于任何List類型的Foldable對象。leftFold方法將取A并使用A構造List[A]。

一種更好的寫法:

scala>importscala.language.implicitConversions
importscala.language.implicitConversions

scala>implicitclassListFoldableOpt[A](list:List[A])(implicitfold:Foldable[List]){
|defleftFold[B](zero:B)(fn:(B,A)=>B):B=
|fold.leftFold(list)(zero)(fn)
|}

scala>List(1,2,3).leftFold(0)(_+_)//6

這里先收一下,回到Rust中。

Rust中的很多不同結構都實現了map函數,比如: Option, Result, Iterator, and Future.

但是, 在Rust里面,還不能編寫可以給多種類型實現的通用Functortrait, 就像我剛才上面寫的trait Functor[F[_]]。通常呢 在Rust里面是單個類型單獨去實現map。例如,我這里自己寫了一個MyOption和MyResult枚舉類, 并實現了map方法.

#[derive(Debug,PartialEq)]
enumMyOption{
Some(A),
None,
}

implMyOption{
fnmapB,B>(self,f:F)->MyOption{
matchself{
MyOption::Some(a)=>MyOption::Some(f(a)),
MyOption::None=>MyOption::None,
}
}
}

#[test]
fntest_option_map(){
assert_eq!(MyOption::Some(5).map(|x|x+1),MyOption::Some(6));
assert_eq!(MyOption::None.map(|x:i32|x+1),MyOption::None);
}

#[derive(Debug,PartialEq)]
enumMyResult{
Ok(A),
Err(E),
}

implMyResult{
fnmapB,B>(self,f:F)->MyResult{
matchself{
MyResult::Ok(a)=>MyResult::Ok(f(a)),
MyResult::Err(e)=>MyResult::Err(e),
}
}
}

#[test]
fntest_result_map(){
assert_eq!(MyResult::Ok(5).map(|x|x+1),MyResult::(6));
assert_eq!(MyResult::Err("hello").map(|x:i32|x+1),MyResult::Err("hello"));
}

上面的幾個例子都是直接在自己的結構中定義的map方法。如果沒有GATs, 就不可能將map定義為一個trait的方法。這是為什么呢?下面是一個在Rust里面簡單的Functortrait實現,以及Option的實現.

traitNaiveFunctor{
typeT;
fnmap(self,f:F)->Self
where
F:FnMut(Self::T)->Self::T;
}

implNaiveFunctorforOption{
typeT=A;
fnmapA>(self,mutf:F)->Option{
matchself{
Some(a)=>Some(f(a)),
None=>None,
}
}
}

在上面的trait定義中,先給NaiveFunctor內部的值定義了一個關聯類型T。給Optionimpl這個trait,T=A。這就是問題所在。Rust將T硬編碼為一種類型A,因為通常在map函數中,希望返回的類型是B,但在之前版本穩定的Rust中,沒有辦法說"我想要一個既能與NaiveFunctor關聯的類型,又要求這個類型和關聯類型有一點不一樣。

這就是泛型關聯類型發揮作用的地方了。

多態Functor的實現

為了得到一個多態Functor.我想要的是:"我的類型最終應該是我在其中包裹的類型".例如,對于Option,我想說的是"如果我有一個Option,那么它肯定包含一個A類型,但如果它包含一個B類型,它將是Option"

這里就需要使用泛型關聯類型.

traitFunctor{
typeUnwrapped;
typeWrapped:Functor;
fnmap(self,f:F)->Self::Wrapped
where
F:FnMut(Self::Unwrapped)->B;
}

說明下上面的寫法:

每個Functor都有一個關聯的Unwrapped類型.

還有另一個關聯類型Wrapped,它與Self類似,但有一個不同的包裝值

和前面例子一樣, map接受兩個參數的一個是:self和一個函數

函數形參將從當前關聯的Unwrapped值映射到一個新的類型B

map的輸出是一個Wrapped

有點抽象。具體點現在看下Option類型是什么樣子的

implFunctorforOption{
typeUnwrapped=A;
typeWrapped=Option;

fnmapB,B>(self,mutf:F)->OptionwhereF:FnMut(A)->B{
matchself{
Some(x)=>Some(f(x)),
None=>None,
}
}
}

#[test]
fntest_option_map(){
assert_eq!(Some(5).map(|x|x+1),Some(6));
assert_eq!(None.map(|x:i32|x+1),None);
}

編譯通過,非常優雅。

類型類

在Haskell和Scala中,其實是不需要這種泛型關聯類型的。事實上,Haskell中Functors不使用任何關聯類型。Haskell中Functor的類型類遠遠早于其他語言中關聯類型的出現。為了進行比較,先看看它是什么樣子。

classFunctorfwhere
map::(a->b)->fa->fb

instanceFunctorOptionwhere
mapfoption=
caseoptionof
Somex->Some(fx)
None->None
traitFunctor[F[_]]{
defmap[A,B](fa:F[A])(f:A=>B):F[B]
}

把它轉換成Rust就是如下:

traitHktFunctor{
fnmapB>(self:Self,f:F)->Self;
}

implHktFunctorforOption{
fnmapB>(self:Option,f:F)->Option{
matchself{
Some(a)=>Some(f(a)),
None=>None,
}
}
}

但是上面的代碼是編譯不通過的。因為我試圖給Self提供類型參數。但是在Rust中, 單獨一個Option不是一個類型. Option要成為一個類型,必須有一個類型參數.比如: Option 是一個類型. Option卻不是.

相反,在Haskell中,Maybe Int是kind type的一種類型。Maybe是類型構造函數,類型為type -> type。但是出于創建類型類和實例的目的,可以將Maybe處理為具有自己的類型。Haskell中的Functor作用于type->type。

這就是我所說的"高階類型": 就是說我可以寫出擁有類型的類型(Kind)。

Pointer 的實現

Haskell中有一個有爭議的類型類叫做Pointed。之所以有爭議的,是因為它引入了一個類型類,但沒有與它相關的任何laws。我想在Rust中實現下Pointed。

什么是Pointed

Pointed的思想很簡單:將一個值包裝成一個類似Functor的東西。比如:在Option的情況下,它就用Some包裝它。在Result中,它使用Ok。

對于Vec,它是一個單值向量。與Functor不同,這里是一個靜態方法,因為我們沒有現有的Point值要改。讓我們看看它在Rust中的實現。

traitPointed:Functor{
fnwrap(t:T)->Self::Wrapped;
}

implPointedforOption{
fnwrap(t:T)->Self::Wrapped{
Some(t)
}
}

這里需要注意的是: 我根本沒有在Option實現中使用A類型參數。

還有一點值得注意。調用wrap的結果返回的是Self::Wrapped。關于Self::Wrapped,到底是什么?從之前Functor的定義中,確切地知道一件事:Wrapped必須是一個Functor的。








審核編輯:劉清

  • GAT
    GAT
    +關注

    關注

    0

    文章

    7

    瀏覽量

    6350
  • API接口
    +關注

    關注

    1

    文章

    84

    瀏覽量

    10457
  • Rust
    +關注

    關注

    1

    文章

    229

    瀏覽量

    6619

原文標題:Rust中GAT和高階類型

文章出處:【微信號:Rust語言中文社區,微信公眾號:Rust語言中文社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    高階濾波器的設計

    高階濾波器的設計 實現高階濾波器的方法是把基高階函數分解成多個二階因式之積,每個二階因式用對應的二階濾波器來實現,將這些二階濾波器串接起來
    發表于 05-23 15:39 ?7243次閱讀
    <b class='flag-5'>高階</b>濾波器的設計

    高階程控濾波器的研究

    高階程控濾波器的研究作者:李鳴華關鍵詞:巴氏濾波網絡,高階程控濾波器,儀表測試摘要:本文提出了一種基于二階巴氏濾波網絡的高階程控濾波器的實現原理與方法,在儀表測試及工程應用領域有一定的實用價值。濾波
    發表于 12-05 09:08

    高階系統的時域分析

    高階系統的時域分析
    發表于 04-10 20:58

    SAR與ADC不同輸入類型

    作者: Amit Kumbasi 今天,我們繼續講解與逐次逼近寄存器 (SAR) 數模轉換器 (ADC) 輸入類型有關的內容。在之前的部分中,我研究了輸入注意事項和SAR ADC之間的性能比較。在這
    發表于 09-11 14:49

    怎樣設計一個高階帶阻濾波器

    為什么網上高階的帶通濾波器比比皆是,而帶阻濾波器只有最高兩階的?如果有高階的(最好是四階的)帶阻濾波器請發個設計圖 我想學習學習
    發表于 06-09 18:20

    什么是高階函數?

    高階函數是將其他函數作為形參,或者以函數作為返回結果。因為在Scala中,函數是***。這個術語可能聽起來有點亂,但實際上我們把 以函數作為形參或以函數作為返回結果的函數和方法統稱為高階函數。
    發表于 11-05 06:46

    如何實現一種環路濾波器(高階)參數的設計?

    數字鎖相環是什么?造成PLL異常鎖定的原因是什么?如何實現一種環路濾波器(高階)參數的設計?
    發表于 06-22 06:53

    怎樣使用typedef定義一個數據類型

    typedef與#define有哪些不同?怎樣使用typedef定義一個數據類型
    發表于 02-25 07:56

    HLS高階綜合的定義及挑戰

    HLS高階綜合(high level synthesis)在被廣泛使用之前,作為商業技術其實已經存在了20多年。設計團隊對于這項技術可以說呈現出兩極化的態度:要么堅信它是先進技術之翹楚,要么對其持謹慎懷疑態度。
    發表于 11-04 13:45 ?3364次閱讀

    基于線性網格創建高階網格

    在 CFD 模擬使用的多種網格生成方法中,高階網格是一種能夠實現精度、分辨率和計算成本平衡的有效方法。高階網格劃分的目標是利用高階多項式曲線的優勢為 CFD 計算創建網格,從而實現在復雜系統環境下提供比線性網格更高的精度。
    的頭像 發表于 09-22 10:30 ?959次閱讀

    Rust中GAT和高階類型

    Rust在類型系統級別上與Haskell,Scala有許多相似之處。
    的頭像 發表于 11-07 10:21 ?1192次閱讀

    用戶自定義類型

    SystemVerilog還為工程師定義新的數據類型提供了一種機制。用戶定義的數據類型允許從現有數據類型創建新的
    的頭像 發表于 02-09 14:53 ?1083次閱讀
    用戶自<b class='flag-5'>定義</b><b class='flag-5'>類型</b>

    光腔的損耗有哪些類型

    取決于腔的類型和幾何尺寸。幾何損耗的高低依模式的不同而異,高階橫模損耗大于低階橫模損耗。是非穩腔的主要損耗。
    的頭像 發表于 02-25 15:55 ?1144次閱讀

    定義數據類型

    在運算之前我們必須首先定義出數據類型,定義出腳本支持的數據類型,這是運算的基礎。 這一小節我們將定義出數據
    的頭像 發表于 03-03 10:10 ?963次閱讀

    UHDI及高階封裝技術對檢測系統的挑戰

    高階封裝技術相關的復雜性增加使含有多種芯片類型及小型化元器件的PCB設計更復雜。此外,在2.5D和3D封裝等高階封裝解決方案的推動下,行業朝著更高密度和更小間距的方向發展,對檢測設備提出了顯著需求。
    發表于 10-23 15:16 ?466次閱讀
    UHDI及<b class='flag-5'>高階</b>封裝技術對檢測系統的挑戰
    主站蜘蛛池模板: 日日噜噜噜夜夜爽爽狠狠视频| 国产日本特黄特色大片免费视频| 免费色视频| 激情五月视频| 国产精品天天在线| 欧美高h| 成人激情综合网| 国产成人精品三级| 一品毛片| 欧美日本一区二区| 久久mimi色| 综合黄色| 日本高清午夜色wwwσ| 亚洲性一区| 天天免费| 香蕉久久影院| 亚洲国产欧美视频| 全亚洲最大的777io影院| 中国一级特黄视频| 爱爱免费视频网站| 免费看一级黄色录像| 青青伊人91久久福利精品| 狠狠狠色丁香婷婷综合激情| 亚洲美女啪啪| 无遮挡一级毛片| 黄色成人毛片| 久操免费视频| sss欧美华人整片在线观看| 亚洲一本之道在线观看不卡| 5g影院天天爽 | 色国产精品| 韩国电影天堂| 日本口工禁漫画无遮挡全彩| 欧美极品色影院| 欧美一区二区三区黄色| 99国产精品农村一级毛片| 日本护士69xx00| 色综合一区二区三区| 成人拍拍视频| 永久免费看的啪啪网站| 特级生活片|