Algebrallinen tyyppiteoria
Lainauksen säännöt
- Jokaisella hetkellä ohjelman suorituksen aikana voi olla
&T
ja&mut T
lainauksia... - Mikä tahansa lukumäärä muuttumattomia lainauksia
&T
- Tai yksi muuttuva lainaus
&mut T
-
Referenssien tulee aina osoittaa validiin
T
n instanssiin
Mikä on tyyppi?
- Tieto luokitellaan tyyppeihin
[i32; 5]
- Myös funktioilla on tyyppi
fn(String) -> usize
- Tyyppi määrittelee ja rajoittaa missä muodossa tieto esiintyy
- Esitys muistissa
- Miten funktio on esitetty muistissa?
[i32; 5]
Algebralliset tietotyypit
- Tulo- ja summatyypit
- Ergonominen
match
- Konkreetti eikä abstrakti
- Tietoon pääsee helposti käsiksi,
koska tiellä ei ole turhia abstraktioita- Vertaa luokkiin ja olioihin
Tulotyyppi
T = bool × i32 × Vec<f64>
- Tulotyypit sisältävät monta ilmentymää kerralla
T
:n konstruktoiminen vaatii ilmentymänbool
ista,i32
sta jaVec<f64>
sta
- Tuplet ja structit ovat tulotyyppejä
Summatyyppi
S = A(i32) + B(String)
- Ilmentymän variantit ovat samaa tyyppiä
- Varianteilla on uniikki nimi
- A ja B
- Enumit ovat summatyyppejä
S
ei voi sisältääi32
jaString
samaan aikaan
struct
#![allow(unused)] fn main() { struct Person { age: i32, name: String, } }
Erilaisia struct
eja
#![allow(unused)] fn main() { /// tuple struct struct S(i32, String); }
#![allow(unused)] fn main() { /// unit struct struct S; }
enum
#![allow(unused)] fn main() { enum E { None, Some(i32), Person { name: String, age: i32 }, } }
struct
muistissa
struct S { b: B, c: C }
struct S(B, C)
C
↦
B
enum
muistissa
enum E { A, B, C }
Tag "A"
A
Tag "B"
B
Tag "C"
C
Missä None
?
yobs = {"Python": 1989, "Rust": 2010, "Prolog": 1972}
rust_birth = yobs.get("Rust") # 2010
print(rust_birth + 12) # 2022
java_birth = yobs.get("Java") # None
print(java_birth + 27) # Wat?
java_birth = yobs.get("Java") # None
print(java_birth + 27) # ERROR!!!
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
#![allow(unused)] fn main() { use std::collections::HashMap; let yobs = HashMap::from([ ("Python", 1989), ("Rust", 2010), ("Prolog", 1972), ]); let rust_birth = yobs.get("Rust"); println!("{:?}", rust_birth); // Some(2010) }
HashMap::<K, V>::get
pub fn get(&self, k: &K) -> Option<&V>
let java_birth: Option<&i32> = yobs.get("Java"); // None
println!("{:?}", java_birth.map(|y| y + 12)); // None
Option<T>
#![allow(unused)] fn main() { enum Option<T> { Some(T), None, } }
Variantit eivät ole tyyppejä!
match
#![allow(unused)] fn main() { enum E { /// Unit variant None, /// Newtype variant Some(i32), /// Struct variant Person { name: String, age: i32 }, } let e = E::Some(5); match e { E::Some(num) => dbg!(num), _ => todo!(), }; }
[src/main.rs:11] num = 5
λ
-funktiot (klosuurit)
#![allow(unused)] fn main() { let luvut = (1..12).filter_map( |n| if n % 3 == 0 { Some(n * 2) } else { None } ); for n in luvut { println!("{n}"); } }
Lopuksi
- Täyttäkää viikon 3 palautekysely
- Loppukurssin projekti
- Lukekaa kirjasta 6.2