簡體   English   中英

為什么我們不能在Coq / Agda / Idris的Set / Type上進行模式匹配?

[英]Why we cannot pattern match on Set/Type in Coq/Agda/Idris?

考慮一個接受Set的函數,並返回其字節長度,名為byteLength

byteLength : Set -> Maybe Nat

如果我想直接實現這個函數,我需要在類型參數上進行模式匹配:

byteLength Char = Just 1
byteLength Double = Just 8
byteLength _ = Nothing

但由於不允許在Set / Type上進行模式匹配,因此上述代碼無法編譯。

所以我們必須將接口定義為變通方法

Interface ByteLength a where
    byteLength : Nat

implement ByteLength Char where
    byteLength = 1

並且以更一般的方式,也許我們可以使用TypeRep之類的東西在TypeRep上執行類似的事情和模式匹配。 但TypeRep也被定義為接口。

我認為使用Interface和使用forall是非常不同的,因為Interface意味着“對於某些類型”,而forall意味着“適用於所有類型”。

我想知道為什么這些DT語言不支持Set / Type上的模式匹配,是否有一些我不知道的特殊原因?

在Agda,Idris,Haskell和許多其他語言中,對類型的量化是參數化的 (與允許在類型上匹配的ad-hoc多態相反)。 從實現的角度來看,這意味着編譯器可以從程序中擦除所有類型,因為函數永遠不會在計算上依賴於類型Set的參數。 能夠擦除類型在依賴類型語言中尤其重要,因為類型通常可以成為巨大的表達。

從更理論的角度來看,參數多態是很好的,因為它允許我們通過查看它的類型來推斷函數的某些屬性, 由Phil Wadler雄辯地描述為“自由定理” 我可以嘗試給你這篇論文的要點,但你應該真的去看看它。

當然,有時需要ad-hoc多態來實現一個函數,這就是Haskell和Idris有類型類的原因 (Agda有一個類似的特性叫做實例參數 ,而Coq有規范結構和類型類)。 例如,在Agda中,您可以定義如下記錄:

record ByteLength (A : Set) : Set where
  field
    theByteLength : Nat
open ByteLength

byteLength : (A : Set) {{_ : ByteLength A}} -> Nat
byteLength A {{bl}} = bl .theByteLength

然后你可以通過定義實例為各種類型定義byteLength函數:

instance
  byteLengthChar : ByteLength Char
  byteLengthChar .theByteLength = 1

  byteLengthDouble : ByteLength Double
  byteLengthDouble .theByteLength = 8

使用此代碼, byteLength Char計算結果為1byteLength Double計算結果為8 ,而它會引發任何其他類型的類型錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM