Megosztás a következőn keresztül:


Altípusok és variancia

Q# csak néhány konverziós mechanizmust támogat. Implicit konverziók csak bináris operátorok alkalmazása, feltételes kifejezések kiértékelése vagy tömbkonstans létrehozásakor történhetnek. Ezekben az esetekben meghatározunk egy gyakori szupertípust, és a szükséges átalakításokat automatikusan végrehajtjuk. Az ilyen implicit konverziók mellett a függvényhívásokon keresztüli explicit konverziók is lehetségesek és gyakran szükségesek.

Jelenleg az egyetlen olyan altiprási kapcsolat létezik, amely a műveletekre vonatkozik. Intuitív módon logikus, hogy lehetővé kell tenni egy olyan művelet helyettesítését, amely több, mint a szükséges funktorkészletet támogatja. Konkrétan, bármely két konkrét típus TInTOutesetében és , az altípus-reláció a

    (TIn => TOut) :>
    (TIn => TOut is Adj), (TIn => TOut is Ctl) :>
    (TIn => TOut is Adj + Ctl)

ahol A :> B azt jelzi, hogy B a altípusa A. Másként fogalmazva, szigorúbb, B mint A az ilyen, hogy egy típusú B érték használható, ahol szükség van egy típusú A értékre. Ha egy hívható típus argumentumára (elemére A) támaszkodik, akkor egy típus B argumentuma biztonságosan helyettesíthető, mivel ha az összes szükséges képességet biztosítja.

Ez a fajta polimorfizmus abban az esetben terjed ki a rekordokra, ha egy rekordtípus B egy rekordtípus A altípusa, ha azonos számú elemet tartalmaz, és az egyes elemek típusa a megfelelő elemtípus altípusa a fájlban A. Ezt mélységi altipréssel ismerjük. Jelenleg nem támogatott a szélességi altípus, azaz nincs altípus-kapcsolat két felhasználó által definiált típus vagy felhasználó által definiált típus és bármely beépített típus között. Az operátor megléte unwrap , amely lehetővé teszi, hogy kinyerje az összes megnevezett és névtelen elemet tartalmazó rekordot, megakadályozza ezt.

Megjegyzés

A hívhatók esetében, ha a hívható egy típusú Aargumentumot dolgoz fel, akkor a típus argumentumát Bis képes feldolgozni. Ha egy hívhatót argumentumként ad át egy másik hívhatónak, akkor képesnek kell lennie a típus-aláírás által igényelt bármi feldolgozására. Ez azt jelenti, hogy ha a hívhatónak képesnek kell lennie egy típusú Bargumentum feldolgozására, minden olyan hívható, amely képes egy általánosabb típusú A argumentum feldolgozására, biztonságosan átadható. Ezzel szemben azt várjuk, hogy ha azt követeljük meg, hogy az átadott hívható típusértéket Aadjon vissza, akkor a típus B értékének visszaadására vonatkozó ígéret elegendő, mivel ez az érték minden szükséges képességet biztosít.

A művelet vagy függvény típusa argumentumtípusában a contravariant , a visszatérési típusában pedig a kovariant . A :> B ezért azt jelenti, hogy bármilyen konkrét típus T1esetében,

    (B → T1) :> (A → T1), and
    (T1 → A) :> (T1 → B) 

ahol itt egy függvényt vagy műveletet is jelenthet, és kihagyjuk a jellemzőkre vonatkozó megjegyzéseket. A A és a és az (B → T2)(T2 → A), illetve B az és az helyettesítése (A → T2)(T2 → B) arra a következtetésre vezet, hogy bármely konkrét típus T2esetében,

    ((A → T2) → T1) :> ((B → T2) → T1), and
    ((T2 → B) → T1) :> ((T2 → A) → T1), and
    (T1 → (B → T2)) :> (T1 → (A → T2)), and
    (T1 → (T2 → A)) :> (T1 → (T2 → B)) 

Az indukcióból következik, hogy minden további közvetettség megfordítja az argumentumtípus varianciáját, és változatlanul hagyja a visszatérési típus varianciáját.

Megjegyzés

Ez azt is egyértelművé teszi, hogy a tömbök variancia-viselkedésének milyennek kell lennie; az elemek elemhozzáférési operátoron keresztüli lekérése egy típusú (Int -> TItem)függvény meghívásának felel meg, ahol TItem a tömb elemeinek típusa. Mivel ezt a függvényt implicit módon adja át egy tömb átadásakor, a tömböknek kovariánsnak kell lenniük az elemtípusukban. Ugyanezek a szempontok a nem módosítható, így az egyes elemtípusokra vonatkozó kovariáns rekordokra is kitérnek. Ha a tömbök nem módosíthatók, akkor egy olyan szerkezet megléte, amely lehetővé teszi elemek tömbben való beállítását, és így egy típusú TItemargumentumot vesz fel, azt jelenti, hogy a tömböknek is contravariantnak kell lenniük. Az elemek lekérését és beállítását támogató adattípusok esetében az egyetlen lehetőség az invariáns, ami azt jelenti, hogy semmilyen altípus-reláció nem létezik; B[]nem a altípusa A[] még akkor sem, ha B a altípusa A. Annak ellenére, hogy a tömbök Q#nem módosíthatók, a kováns helyett invariánsak. Ez például azt jelenti, hogy egy típusérték (Qubit => Unit is Adj)[] nem adható át egy hívhatónak, amely típus argumentumot (Qubit => Unit)[]igényel. A tömbök invariáns megtartása nagyobb rugalmasságot tesz lehetővé a tömbök futtatókörnyezetben való kezelésével és optimalizálásával kapcsolatban, de ezt a jövőben át lehet majd vizsgálni.