簡體   English   中英

添加類型級別自然數

[英]Add Type Level Natural Numbers

我假設,不可能在haskell中添加兩個類型級自然數。 這是真的?

假設自然數的定義如下:

class HNat a

data HZero
instance HNat HZero

data HSucc n
instance (HNat n) => HNat (HSucc n)

以類似於以下的方式定義HAdd是否合適:

class (HNat n1, HNat n2, HNat ne) => HAdd n1 n2 ne | n1 n2 -> ne
instance             HAdd HZero HZero HZero
instance (HNat x) => HAdd HZero x     x
instance (HNat n1 
         ,HNat x) => HAdd (HSucc n1)  x (HAdd n1 (HSucc x) (???))

您不需要添加HZeroHZero 第二種情況已經涵蓋了這一點。 想想你如何通過對第一個參數的歸納,在術語水平上添加Peano自然:

 data Nat = Zero | Succ Nat

 add :: Nat -> Nat -> Nat
 add Zero     y = y
 add (Succ x) y = Succ (add x y)

現在,如果您正在使用函數依賴項,那么您正在編寫邏輯程序。 因此,不是在右側進行遞歸調用,而是在左側為遞歸調用的結果添加約束:

 class (HNat x, HNat y, HNat r) => HAdd x y r | x y -> r
 instance (HNat y)     => HAdd HZero     y y
 instance (HAdd x y r) => HAdd (HSucc x) y (HSucc r)

您不需要第二個實例中的HNat約束。 它們隱含在類的超類約束上。

這些天,我認為進行這種類型級編程的最好方法是使用DataKindsTypeFamilies 您在術語級別定義:

 data Nat = Zero | Succ Nat

然后你可以使用Nat作為一種類型,也可以作為一種類型 然后,您可以在兩個自然數上定義類型系列,如下所示:

 type family Add (x :: Nat) (y :: Nat) :: Nat
 type instance Add Zero     y = y
 type instance Add (Succ x) y = Succ (Add x y)

這更接近於添加的術語級定義。 此外,使用“提升”類Nat可以使您不必定義諸如HNat類的類。

有可能的。 看一下package type-level-natural-number`type-level-natural-number-operations 兩者都有點舊,但易於使用,后者定義了Plus類型。

無論如何,我會改變你的最后一行到這樣的東西(我沒有測試這是否編譯)。

instance (HNat n1, HNat x, HAdd n1 x y) => HAdd (HSucc n1) x (HAdd n1 x (HSucc y))

基本上,您所做的是以歸納方式定義加法,並且附加約束HAdd n1 xy添加必要的歸納情況。

暫無
暫無

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

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