簡體   English   中英

如何在haskell中證明類型級列表屬性?

[英]How do I prove type-level list properties in haskell?

我有這些類型的家庭:

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

type family Drop n xs where
  Drop  O         xs  = xs
  Drop (S n) (_ : xs) = Drop n xs

type family Length xs where
  Length '[] = O
  Length  (x : xs) = S (Length xs)

在某些時候,GHC 想要證明

forall a. Drop (Length a) (a ++ c) ~ c

我曾經把它推到一些構造函數的上下文中。

我如何普遍證明這個屬性?

好的,所以你的類型家庭很好,你的財產幾乎是正確的。

你要證明的是:

proof :: Drop (Length a) (a ++ c) :~: c

除非你真的不知道ac是什么。 它們是隱式量化的。 您希望它們是明確的,以便我們可以對它們進行歸納。

proof :: (a :: [ k ]) -> (c :: [ k ]) -> Drop (Length a) (a ++ c) :~: c

您會意識到這不會進行類型檢查,因為 Haskell 沒有真正的依賴類型,但有一種解決方法:單例類型 這個想法是創建一個索引類型,以便每個術語對應於用作類型索引的不同類型的一個術語。 我知道這聽起來有點令人困惑,但示例應該可以澄清它。

您可以使用singletons庫或從頭開始構建它們,這就是我在這里要做的。

data family Sing (x :: k)

data SList xs where
  SNil  :: SList '[]
  SCons :: Sing x -> SList xs -> SList (x ': xs)

這里Sing是一個數據族,因此我可以泛指具有單例的事物。 SList是列表類型的單例版本,如您所見, SNil構造函數對應於類型級別[] 同樣, SCons反映:

然后(假設您在某處也有data Nat = O | S Nat的定義)您所追求的證明的簽名是

proof :: SList a -> SList c -> Drop (Length a) (a ++ c) :~: c

請注意,我將您的~更改為:~:這是Data.Type.Equality可用的類型運算符。 唯一的構造函數是Refl ,只有當它的兩個操作數完全相同時才能斷言。

現在我們只需要證明它。 幸運的是,這是一個超級簡單的性質來證明,你只需要對SList a

在基本情況下SList aSNil ,所以你真的想證明Drop (Length '[]) ('[] '++ c) :~: c 因為您使用了類型系列,類型檢查器會立即將其減少為c :~: c 由於兩個操作數相同,我們可以使用Refl構造函數來證明這種情況。

proof SNil _ = Refl

現在是歸納案例。 我們將再次進行模式匹配,這一次了解到SList a的形式為SCons a as a :: Sing xas :: Sing xs 這意味着我們需要證明的是Drop (Length (x ': xs)) ((x : xs) ++ c) :~: c 同樣,您的類型系列將立即開始進行計算並將此目標減少到Drop (Length xs) (xs ++ c) :~: c因為它實際上不需要知道x是什么來進行評估。

事實證明, proof as c (nb。我使用as而不是SCons a as ) 恰好具有所需的類型,因此我們使用它來證明屬性。

這是完整的證據。

proof :: SList a -> SList c -> Drop (Length a) (a ++ c) :~: c
proof SNil _ = Refl
proof (SCons a as) cs = proof as cs

為了使這些工作,您需要所有這些語言擴展:

{-# LANGUAGE GADTs #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE KindSignatures #-}

暫無
暫無

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

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