Bad
İşlevinin ilk oluşumuna 'negatif' denir, çünkü bir işlev bağımsız değişkenini temsil eder, yani işlev okunun solunda bulunur (bkz . Philip Wadler tarafından ücretsiz olarak yinelenen türler). Teriminin 'olumsuz bir pozisyona' kökeni kavramına kaynaklanmaktadır tahmin contravariance ( 'kontra' araçları ters).
Türün negatif konumda tanımlanmasına izin verilmez, çünkü birisini kullanarak sonlandırmayan programlar yazabilir, yani güçlü normalizasyon varlığında başarısız olur (daha fazlası aşağıdadır). Bu arada, 'katı pozitiflik' kuralının adının nedeni budur: negatif pozisyonlara izin vermiyoruz.
Bad
Sonlandırmaya neden olmadığı için ikinci oluşumuna izin veriyoruz ve yinelenen bir veri türünde ( yapıcısının son okundan önceBad
) bir noktada tanımlanmış ( ) türünü kullanmak istiyoruz .
Aşağıdaki tanım olmadığını anlamak önemlidir değil sıkı pozitiflik kuralını ihlal ediyor.
data Good : Set where
good : Good → Good → Good
Kural, yalnızca yapıcı argümanları için geçerlidir (her ikisi Good
de bu durumdadır ) ve bir kurucu için geçerli değildir (ayrıca bkz. Adam Chlipala'nın " Bağımlı Türlerle Sertifikalı Programlama ").
Katı pozitifliği ihlal eden başka bir örnek:
data Strange : Set where
strange : ((Bool → Strange) → (ℕ → Strange)) → Strange
^^ ^
this Strange is ...this arrow
to the left of...
Negatif pozisyonlar hakkındaki bu cevabı da kontrol etmek isteyebilirsiniz .
Feshetmeyle ilgili daha fazla bilgi ... Referans verdiğiniz sayfa bazı açıklamalar içerir (Haskell'deki bir örnekle birlikte):
Kesinlikle olumlu olmayan bildirimler reddedilir çünkü biri onları kullanarak sonlandırıcı olmayan bir işlev yazabilir. Yukarıdan Bad veri türünü kullanarak bir döngü tanımı nasıl yazabileceğini görmek için bkz . BadInHaskell .
Ocaml'da özyinelemeli davranışı doğrudan (!) Kullanmadan özyinelemeli davranışın nasıl uygulanacağını gösteren benzer bir örnek :
type boxed_fun =
| Box of (boxed_fun -> boxed_fun)
(* (!) in Ocaml the 'let' construct does not permit recursion;
one have to use the 'let rec' construct to bring
the name of the function under definition into scope
*)
let nonTerminating (bf:boxed_fun) : boxed_fun =
match bf with
Box f -> f bf
let loop = nonTerminating (Box nonTerminating)
nonTerminating
Fonksiyon "paketten çıkarır" orijinal argümanı olan argüman ve elma ondan bir fonksiyonu. Burada önemli olan, çoğu tip sistemin fonksiyonların kendilerine geçmesine izin f f
vermemesidir, bu nedenle, f
daktiloyu tatmin edecek bir tür olmadığından , tipik bir kontrol olmayacaktır. Tip sistemlerinin kullanılmasının nedenlerinden biri, kendi kendine uygulamayı devre dışı bırakmaktır ( buraya bakın ).
Yukarıda tanıttığımız gibi kaydırma veri türleri tutarsızlık yolunda bu barikatı atlatmak için kullanılabilir.
Sonlandırıcı olmayan hesaplamaların mantık sistemlerine tutarsızlıklar getirdiğini eklemek istiyorum. Agda ve Coq durumunda, False
tümevarımsal veri türünde herhangi bir kurucu yoktur, bu nedenle hiçbir zaman False türünde bir kanıt terimi oluşturamazsınız. Fakat sonlandırıcı olmayan hesaplamalara izin verildiyse , bunu örneğin Coq'ta yapabilirdi:
Fixpoint loop (n : nat) : False = loop n
Sonra loop 0
daktilo vererek loop 0 : False
, Curry-Howard yazışmaları altında yanlış bir önerimiz olduğu anlamına gelir.
Upshot : tümevarım tanımları için katı pozitiflik kuralı, mantık için felaket olan sonlandırılmamış hesaplamaları önler.
A
ve sonunda (yığın tabanlı dillerde) yığını patlayabilir.