簡體   English   中英

如何在沒有類的情況下歸納證明類型相等?

[英]How to prove type equality inductively without classes?

我試圖證明類型級列表的關聯性,這種方式允許我在等價類型之間進行轉換,而無需攜帶任何約束。

假設連接的標准定義:

type family (++) (xs :: [k]) (ys :: [k]) :: [k] where
  '[] ++ ys = ys
  (x ': xs) ++ ys = x ': (xs ++ ys)

假設,我得到一個 function:

given :: forall k (a :: [k]) (b :: [k]) (c :: [k]). Proxy ((a ++ b) ++ c)
given = Proxy  -- Proxy is just an example

我想稱之為 function 然后使用關聯性:

my :: forall k (a :: [k]) (b :: [k]) (c :: [k]). Proxy (a ++ (b ++ c))
my = given @k @a @b @c  -- Couldn't match type ‘(a ++ b) ++ c’ with ‘a ++ (b ++ c)’

這種類型相等確實不是微不足道的,所以編譯器不理解它並不奇怪,但是我可以證明它,不幸的是。 我不知道如何說服編譯器我可以。

我自然的第一個想法是做類似的事情:

proof :: forall k (a :: [k]) (b :: [k]) (c :: [k]). (a ++ (b ++ c)) :~: ((a ++ b) ++ c)
proof = _

然后將我的 function 更改為:

my :: forall k (a :: [k]) (b :: [k]) (c :: [k]). Proxy (a ++ (b ++ c))
my = case proof @k @a @b @c of Refl -> given @k @a @b @c

但是我仍然需要定義proof ,為此我需要對其類型 arguments 執行歸納。 我知道對 Haskell 中的類型進行歸納的唯一方法是定義一個類型 class,但是我必須在my的類型中添加相應的約束,我不想這樣做 - 事實上它given的調用和強制結果是一個“實現細節”。

有沒有辦法在不訴諸不安全假設的情況下證明 Haskell 中的這種類型相等?

不,如果沒有類型類約束,您無法證明這一點,因為它不正確。 特別是,這里有一個反例:

Any ++ ([] ++ []) -- reduces to Any ++ []
(Any ++ []) ++ [] -- does not reduce

要排除Any的(愚蠢)存在,您必須使用沒有Any實例的類型類; 沒有其他選擇。

暫無
暫無

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

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