मैंने Haskell के इस छोटे से हिस्से को यह पता लगाने के लिए लिखा कि GHC यह कैसे साबित करता है कि प्राकृतिक संख्या के लिए, आप केवल यहां तक कि आधा कर सकते हैं:
{-# LANGUAGE DataKinds, GADTs, KindSignatures, TypeFamilies #-}
module Nat where
data Nat = Z | S Nat
data Parity = Even | Odd
type family Flip (x :: Parity) :: Parity where
Flip Even = Odd
Flip Odd = Even
data ParNat :: Parity -> * where
PZ :: ParNat Even
PS :: (x ~ Flip y, y ~ Flip x) => ParNat x -> ParNat (Flip x)
halve :: ParNat Even -> Nat
halve PZ = Z
halve (PS a) = helper a
where helper :: ParNat Odd -> Nat
helper (PS b) = S (halve b)
कोर के प्रासंगिक हिस्से बन जाते हैं:
Nat.$WPZ :: Nat.ParNat 'Nat.Even
Nat.$WPZ = Nat.PZ @ 'Nat.Even @~ <'Nat.Even>_N
Nat.$WPS
:: forall (x_apH :: Nat.Parity) (y_apI :: Nat.Parity).
(x_apH ~ Nat.Flip y_apI, y_apI ~ Nat.Flip x_apH) =>
Nat.ParNat x_apH -> Nat.ParNat (Nat.Flip x_apH)
Nat.$WPS =
\ (@ (x_apH :: Nat.Parity))
(@ (y_apI :: Nat.Parity))
(dt_aqR :: x_apH ~ Nat.Flip y_apI)
(dt_aqS :: y_apI ~ Nat.Flip x_apH)
(dt_aqT :: Nat.ParNat x_apH) ->
case dt_aqR of _ { GHC.Types.Eq# dt_aqU ->
case dt_aqS of _ { GHC.Types.Eq# dt_aqV ->
Nat.PS
@ (Nat.Flip x_apH)
@ x_apH
@ y_apI
@~ <Nat.Flip x_apH>_N
@~ dt_aqU
@~ dt_aqV
dt_aqT
}
}
Rec {
Nat.halve :: Nat.ParNat 'Nat.Even -> Nat.Nat
Nat.halve =
\ (ds_dJB :: Nat.ParNat 'Nat.Even) ->
case ds_dJB of _ {
Nat.PZ dt_dKD -> Nat.Z;
Nat.PS @ x_aIX @ y_aIY dt_dK6 dt1_dK7 dt2_dK8 a_apK ->
case a_apK
`cast` ((Nat.ParNat
(dt1_dK7
; (Nat.Flip (dt2_dK8 ; Sym dt_dK6))_N
; Nat.TFCo:R:Flip[0]))_R
:: Nat.ParNat x_aIX ~# Nat.ParNat 'Nat.Odd)
of _
{ Nat.PS @ x1_aJ4 @ y1_aJ5 dt3_dKa dt4_dKb dt5_dKc b_apM ->
Nat.S
(Nat.halve
(b_apM
`cast` ((Nat.ParNat
(dt4_dKb
; (Nat.Flip
(dt5_dKc
; Sym dt3_dKa
; Sym Nat.TFCo:R:Flip[0]
; (Nat.Flip (dt_dK6 ; Sym dt2_dK8))_N
; Sym dt1_dK7))_N
; Sym dt_dK6))_R
:: Nat.ParNat x1_aJ4 ~# Nat.ParNat 'Nat.Even)))
}
}
end Rec }
मुझे पता है कि फ्लिप प्रकार के परिवार के उदाहरणों के माध्यम से प्रकारों को कास्टिंग करने का सामान्य प्रवाह है, लेकिन कुछ चीजें हैं जो मैं पूरी तरह से पालन नहीं कर सकता हूं:
- का मतलब क्या है
@~ <Nat.Flip x_apH>_N
? क्या यह एक्स के लिए फ्लिप उदाहरण है? इससे अलग कैसे होता है@ (Nat.Flip x_apH)
? मुझे दोनों में दिलचस्पी है< >
और_N
पहली कास्ट के बारे में halve
:
- क्या करते हैं
dt_dK6
,dt1_dK7
औरdt2_dK8
खड़े रहते हैं? मैं समझता हूं कि वे कुछ प्रकार के तुल्यता प्रमाण हैं, लेकिन कौन सा है? - मैं समझता हूं कि यह
Sym
एक समतुल्यता के पीछे से चलता है - क्या करते
;
हैं? क्या तुल्यता प्रमाण केवल क्रमिक रूप से लागू होते हैं? - ये क्या हैं
_N
और_R
प्रत्यय हैं? - कर रहे हैं
TFCo:R:Flip[0]
औरTFCo:R:Flip[1]
फ्लिप के उदाहरण?