Institute of Computer Science
  1. Courses
  2. 2023/24 fall
  3. Functional Programming (LTAT.03.019)
ET
Log in

Functional Programming 2023/24 fall

  • Üldinfo
    • Õppekorraldus
  • Loeng
    • Baasväärtused ja tüübid
    • 𝜆-arvutus
    • Kõrgemat järku funktsioonid
    • Interaktiivne programmeerimine
    • Uute tüüpide loomine
    • Liidesed
    • Sisend-Väljund
    • Laiskus
    • Lihtsalt tüübitud 𝜆-arvutus
    • Tüübituletus
    • Sõltuvad tüübid
    • Tõestamine Idrises
    • Kvantitatiivne tüübiteooria
  • Praktikum
    • KKK
    • Installimine
    • Kodutöö 1
    • Kodutöö 2
    • Kodutöö 3
    • Kodutöö 4
    • Kodutöö 5
    • Kodutöö 6
    • Kodutöö 7
    • Kodutöö 8
    • Kodutöö 9
    • Kodutöö 10
    • Kodutöö 11
    • Kodutöö 12
    • Kordamine
    • Projektid
  • Moodle
  • Zulip (sisselogides näed linki)

Kodutöö 11

Tüübituletus ja sõltuvad tüübid

Selles praktikumis harjutame tüübituletust ning programmeerime sõltuvate tüüpidega.

Tüübituletus

Ülesanne 1

Lihtsustuseks:

  • ei pea kirjutama xᵅ ∈ Γ
  • kitsendusi ei pea kirjutama puu sisse (mis oli slaididel roheline)

"Joonista" tüübituletuspuu, kirjuta välja kõik kitsendused ja lahenda kogu avaldise tüüp ɣ2 järgnevatele avaldistele:

  1. ⊢ (λxᵅ¹. ((λyᵅ². yᵅ³)ˠ¹ xᵅ⁴)ᵝ¹)ˠ²
  2. ⊢ (λxᵅ¹. (xᵅ² (λyᵅ³. yᵅ⁴)ˠ¹)ᵝ¹)ˠ²
  3. ⊢ (λxᵅ¹. ((λyᵅ². (λzᵅ³. yᵅ⁴)ˠ¹)ˠ³ xᵅ⁵)ᵝ¹)ˠ²
  4. ⊢ (λxᵅ¹. ((λyᵅ². (λzᵅ³. zᵅ⁴)ˠ¹)ˠ³ xᵅ⁵)ᵝ¹)ˠ²

Sõltuvate tüüpidega programmeerimine

Mitmedimensioonilised punktid

Olles loengus tutvunud tüüpide arvutamise kontseptsiooniga, saab defineerida näiteks kahedimensioonilise punkti tüübi:

punkt2d : Type
punkt2d = (Double, Double)

ning seda üldistades defineerida funktsiooni, mis arvutab sõltuvalt naturaalarvulisest sisendist sellemõõtmelisse dimensiooni kuuluva punkti tüübi:

punkt : Nat -> Type
punkt Z     = Unit
punkt (S Z) = Double
punkt (S n) = (Double, punkt n)

Näiteks:

xy : punkt 2
xy = (2.0,4.0)

xyz : punkt 3
xyz = (3.0,6.0,3.0)

Ülesanne 2 - nullpunkt

Erinevate dimensioonide nullpunktide arvutamine. Kirjuta funktsioon, mis arvutab vastavalt naturaalarvulisele sisendile sellelemõõtmelise dimensiooni nullpunkti:

nullpunkt : (d : Nat) -> punkt d
nullpunkt d = ?undefined

Näiteks:

 nullpunkt 0 == ()
 nullpunkt 1 == 0.0
 nullpunkt 2 == (0.0, 0.0)

Ülesanne 3 - add -- liida kahe punkti vastavad koordinaadid

add: (d:Nat) -> punkt d -> punkt d -> punkt d
add d x y = ?add_rhs

Näiteks:

 add 0 () () == ()
 add 1 1.0 2.0 == 3.0
 add 3 (0.2, 0.2, 4.0) (1.0, 2.0, 0.2) == (1.2, 2.2, 4.2)

Ülesanne 4 - sum - liida kõigi listis olevate punktide koordinaadid

Kirjuta funktsioon, mis võtab sisse naturaalarvu ja sellele vastavasse dimensiooni kuuluvate punktide listi ning tagastab punkti, mille koordinaatideks on teise argumendina saadud listis olevate punktide vastavate koordinaatide summa, kasutades selleks eeldefineeritud funktsioone nullpunkt ja add:

sum : (d : Nat) -> List (punkt d) -> punkt d
sum d xs = ?sum_rhs

Näiteks:

 sum 0 [] == ()
 sum 2 [(1.0,1.0), (2.0,2.0)] == (3.0, 3.0)

Vektorid

Kõige klassikalisem näide Idrise sõltuvatest tüüpidest on vektorid. Vektorid on listid, mis on parametriseeritud nende pikkuse suhtes. See tähendab, et lisaks listile endale sisaldub tüübis alati ka selle pikkus.

data Vect : (k : Nat) -> (a : Type) -> Type where 
  Nil  : Vect Z a
  (::) : a -> Vect k a -> Vect (S k) a

Eq a => Eq (Vect k a) where
    [] == []             = True
    (x :: y) == (z :: w) = x==z && y==w

Väärtuse tüüp on staatiline (ehk kompileerimisaegne) info selle väärtuse kohta. Tüübi täpsustamisega liigutame osa dünaamilist infot staatiliseks. S.t., kui mingis programmis on listide pikkused teada (või väga selge loogikaga), siis on mõistlik kasutada vektoreid. Või siis vastupidi: kui listi pikkust pole teada, siis pole selles kohas mõtet vektoreid kasutada.

Kahe vektori konkateneerimise funktsioon on seega defineeritud kui

append : Vect n a -> Vect m a -> Vect (n + m) a
append []        ys = ys
append (x :: xs) ys = x :: append xs ys

Ülesanne 5 - zipVect

zipVect : Vect n a -> Vect n b -> Vect n (a,b)
zipVect = ?zipVect_rhs

Näiteks:

 zipVect [1,2,3] ['a', 'b', 'c'] == [(1, 'a'), (2, 'b'), (3, 'c')]

Ülesanne 6 - replaceVect

Asendamine vektorites.

replaceVect : a -> (n:Nat) -> Vect (1+n+k) a -> Vect (1+n+k) a
replaceVect = ?replaceVect_rhs

Näiteks:

  replaceVect 'x' 0 ['a','b','c','d'] == ['x', 'b', 'c', 'd']
  replaceVect 'x' 1 ['a','b','c','d'] == ['a', 'x', 'c', 'd']
  replaceVect 'x' 2 ['a','b','c','d'] == ['a', 'b', 'x', 'd']

Ülesanne 7* - takeVec

alguse võtmine vektoritest

min : Nat -> Nat -> Nat 
min 0 y = 0
min (S k) 0 = 0
min (S k) (S j) = S (min k j)

takeVec : (n:Nat) -> {m:Nat} -> Vect m a -> Vect (min n m) a
takeVec n {m} xs = ?takeVec1

Näiteks:

  takeVec 4 [1,2,3,4,5,6,7] == [1, 2, 3, 4]
  takeVec 0 [1,2,3,4,5,6,7] == []
  takeVec 100 [1,2,3,4,5,6,7] == [1, 2, 3, 4, 5, 6, 7]
  • Institute of Computer Science
  • Faculty of Science and Technology
  • University of Tartu
In case of technical problems or questions write to:

Contact the course organizers with the organizational and course content questions.
The proprietary copyrights of educational materials belong to the University of Tartu. The use of educational materials is permitted for the purposes and under the conditions provided for in the copyright law for the free use of a work. When using educational materials, the user is obligated to give credit to the author of the educational materials.
The use of educational materials for other purposes is allowed only with the prior written consent of the University of Tartu.
Terms of use for the Courses environment