ความละเอียดประเภทรูที่ผิดปกติ


105

ฉันเพิ่งค้นพบว่ารูประเภทที่รวมกับการจับคู่รูปแบบบนการพิสูจน์ให้ประสบการณ์ที่ดีเหมือน Agda ใน Haskell ตัวอย่างเช่น:

{-# LANGUAGE
    DataKinds, PolyKinds, TypeFamilies, 
    UndecidableInstances, GADTs, TypeOperators #-}

data (==) :: k -> k -> * where
    Refl :: x == x

sym :: a == b -> b == a
sym Refl = Refl 

data Nat = Zero | Succ Nat

data SNat :: Nat -> * where
    SZero :: SNat Zero
    SSucc :: SNat n -> SNat (Succ n)

type family a + b where
    Zero   + b = b
    Succ a + b = Succ (a + b)

addAssoc :: SNat a -> SNat b -> SNat c -> (a + (b + c)) == ((a + b) + c)
addAssoc SZero b c = Refl
addAssoc (SSucc a) b c = case addAssoc a b c of Refl -> Refl

addComm :: SNat a -> SNat b -> (a + b) == (b + a)
addComm SZero SZero = Refl
addComm (SSucc a) SZero = case addComm a SZero of Refl -> Refl
addComm SZero (SSucc b) = case addComm SZero b of Refl -> Refl
addComm sa@(SSucc a) sb@(SSucc b) =
    case addComm a sb of
        Refl -> case addComm b sa of
            Refl -> case addComm a b of
                Refl -> Refl 

สิ่งที่ดีจริงๆคือฉันสามารถแทนที่ด้านขวามือของสิ่งRefl -> expปลูกสร้างด้วยรูประเภทและประเภทเป้าหมายของรูของฉันได้รับการอัปเดตด้วยการพิสูจน์ซึ่งค่อนข้างเหมือนกับrewriteแบบฟอร์มใน Agda

อย่างไรก็ตามบางครั้งหลุมก็ไม่สามารถอัปเดตได้:

(+.) :: SNat a -> SNat b -> SNat (a + b)
SZero   +. b = b
SSucc a +. b = SSucc (a +. b)
infixl 5 +.

type family a * b where
    Zero   * b = Zero
    Succ a * b = b + (a * b)

(*.) :: SNat a -> SNat b -> SNat (a * b)
SZero   *. b = SZero
SSucc a *. b = b +. (a *. b)
infixl 6 *.

mulDistL :: SNat a -> SNat b -> SNat c -> (a * (b + c)) == ((a * b) + (a * c))
mulDistL SZero b c = Refl
mulDistL (SSucc a) b c = 
    case sym $ addAssoc b (a *. b) (c +. a *. c) of
        -- At this point the target type is
        -- ((b + c) + (n * (b + c))) == (b + ((n * b) + (c + (n * c))))
        -- The next step would be to update the RHS of the equivalence:
        Refl -> case addAssoc (a *. b) c (a *. c) of
            Refl -> _ -- but the type of this hole remains unchanged...

นอกจากนี้แม้ว่าประเภทเป้าหมายไม่จำเป็นต้องเรียงกันในหลักฐาน แต่ถ้าฉันวางสิ่งทั้งหมดจาก Agda ก็ยังคงตรวจสอบได้ดี:

mulDistL' :: SNat a -> SNat b -> SNat c -> (a * (b + c)) == ((a * b) + (a * c))
mulDistL' SZero b c = Refl
mulDistL' (SSucc a) b c = case
    (sym $ addAssoc b (a *. b) (c +. a *. c),
    addAssoc (a *. b) c (a *. c),
    addComm (a *. b) c,
    sym $ addAssoc c (a *. b) (a *. c),
    addAssoc b c (a *. b +. a *. c),
    mulDistL' a b c
    ) of (Refl, Refl, Refl, Refl, Refl, Refl) -> Refl

คุณมีความคิดว่าทำไมสิ่งนี้จึงเกิดขึ้น (หรือฉันจะเขียนหลักฐานใหม่ด้วยวิธีที่มีประสิทธิภาพได้อย่างไร)


8
คุณไม่คาดหวังมากไปหน่อยเหรอ? การจับคู่รูปแบบกับการพิสูจน์ความเท่าเทียมกำลังสร้างความเท่าเทียมกัน (แบบสองทิศทาง) ยังไม่ชัดเจนว่าคุณต้องการนำไปใช้กับประเภทเป้าหมายที่ไหนและในทิศทางใด ตัวอย่างเช่นคุณสามารถละเว้นการsymโทรเข้าmulDistL'และรหัสของคุณจะยังคงตรวจสอบอยู่
kosmikus

1
อาจเป็นไปได้ว่าฉันคาดหวังมากเกินไป อย่างไรก็ตามในหลาย ๆ กรณีมันใช้งานได้เช่นเดียวกับใน Agda ดังนั้นจึงยังมีประโยชน์ในการค้นหาความสม่ำเสมอของพฤติกรรม ฉันไม่ได้มองโลกในแง่ดีเนื่องจากเรื่องนี้น่าจะมีส่วนเกี่ยวข้องอย่างลึกซึ้งกับบาดาลของเครื่องตรวจชนิด
AndrásKovács

1
คำถามของคุณค่อนข้างตรงไปตรงมา แต่คุณสามารถดึงข้อพิสูจน์เหล่านี้ออกมาได้โดยใช้ชุดตัวรวมเหตุผลเชิงเหตุผลà la Agda Cf. การพิสูจน์แนวคิดนี้
Gallais

คำตอบ:


1

หากคุณต้องการสร้างค่าที่เป็นไปได้ทั้งหมดคุณสามารถเขียนฟังก์ชันเพื่อทำเช่นนั้นได้ไม่ว่าจะเป็นขอบเขตที่ระบุหรือระบุไว้

อาจเป็นไปได้มากที่จะใช้เลขคริสตจักรระดับประเภทหรือบางอย่างเพื่อบังคับใช้การสร้างสิ่งเหล่านี้ แต่มันเกือบจะมากเกินไปสำหรับสิ่งที่คุณอาจต้องการ / จำเป็น

นี่อาจไม่ใช่สิ่งที่คุณต้องการ (เช่น "ยกเว้นการใช้เพียงแค่ (x, y) ตั้งแต่ z = 5 - x - y") แต่มันสมเหตุสมผลกว่าการพยายามบังคับใช้ข้อ จำกัด บางอย่างในระดับประเภทเพื่ออนุญาตให้ใช้ได้ ค่า


-3

เกิดขึ้นเนื่องจากค่าถูกกำหนดในขณะทำงาน มันสามารถทำให้เกิดการเปลี่ยนแปลงของค่าขึ้นอยู่กับสิ่งที่ป้อนในเวลาทำงานดังนั้นจึงถือว่าหลุมนั้นได้รับการอัปเดตแล้ว


3
แน่นอนว่าค่าจะถูกกำหนดที่รันไทม์ แต่ไม่มีส่วนเกี่ยวข้องกับคำถาม ข้อมูลที่จำเป็นมีอยู่แล้วจากการจับคู่รูปแบบบน GADT
int_index
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.