簡體   English   中英

如何讓 GHC 識別此代碼段中的 SingI 實例?

[英]How do I make the GHC recognize a SingI instance in this snippet?

有一個關於單身人士的問題

我有一個提升的數據類型a ,我a其中適當地實例化了data family Sing (a :: Foo)

我也有一個類型家族Bar (a :: Foo) (b :: Foo) :: Foo

在繁忙的功能中,我有:

(\(x :: Sing n) (y :: Sing m) -> doThingsWith (sing :: Sing (Bar n m)))

但我不確定應該把SingI約束放在SingI

有關更多詳細信息,我的類型是

data PNat = NZ | NS PNat

data instance Sing (n :: PNat) where
  SNZ :: Sing 'NZ
  SNS :: Sing (m :: PNat) -> Sing ('NS m)

我的字體家族是

type family NPlus (n :: PNat) (m :: PNat) :: PNat where
  NPlus NZ y = y
  NPlus (NS x) y = NS (NPlus x y)

現在,我實際上能夠手動寫出顯式單例改組:

nPlus :: forall n m nm. (NPlus n m ~ nm) => Sing n -> Sing m -> Sing nm
nPlus SNZ y = y
nPlus (SNS x) y = SNS (nPlus x y)

這編譯得很好......我可以做到

\x y -> nPlus x y

但我覺得我應該能夠在這里使用singI並讓singI系列完成這兩項工作。 此外,我也有很多這樣的功能,我寧願不必為每個功能都做。

我確實打開了 ScopedTypeVariables。

謝謝你們


編輯:啊,我剛剛意識到SingI實例不是自動派生的; 我挑了一個:

instance SingI NZ where
  sing = SNZ

instance SingI n => SingI (NS n) where
  sing = SNS sing

不幸的是,當我在上面的 lambda 中使用sing時,GHC 仍然告訴我沒有SingI實例:/

我覺得我應該能夠在這里使用 singI 並讓字體系列完成這兩項工作。

這是做不到的。 我們在singletons有許多 TH 設施的原因是數據和函數定義必須在當前狀態下重復。

慣用的用法是在術語級別定義所有內容一次,然后用 TH 派生其余部分。

-- LANGUAGE KitchenSink
import Data.Singletons.TH
import Data.Singletons.Prelude

$(singletons [d|
  data PNat = NZ | NS PNat deriving (Eq, Show, Ord)

  nPlus :: PNat -> PNat -> PNat
  nPlus NZ y = y
  nPlus (NS x) y = NS (nPlus x y)  |])

這將創建Sing定義、 nPlus的類型族、 SingI實例、 SingKind實例、 Sing的種類限制SPNat類型同義詞、類型族和構造函數的去功能化符號,以及EqOrd類型級類似物,以及可判定的平等 您可以點擊模塊上的:bro:i PNat以准確找出生成的內容。

現在nPlus和類型系列NPlus按預期工作。

提供一些關於SingI的解釋: SingI a => t等價於Sing a -> t 他們甚至編譯成完全相同的核心代碼。 它們之間的唯一區別是Sing -s 是顯式傳遞的,而SingI -s 是隱式傳遞的。 sing提供從SingISing轉換,而singInstance向后轉換。

鑒於此,類似

(SingI (NPlus n m)) => Sing n -> Sing m -> Sing (NPlus n m)

很尷尬,因為它相當於

Sing (NPlus n m) -> Sing n -> Sing m -> Sing (NPlus n m)

它可以實現為一個不做任何加法的常量函數。

那么我們什么時候應該使用SingISing呢? 最方便的方法是在Sing -s 上執行計算,因為我們可以對它們進行模式匹配,並且僅當我們只需要在某處插入或傳遞值時才使用SingI ,但不需要模式匹配或遞歸。

暫無
暫無

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

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