Kodutöö 2
Selles praktikumis harjutame funktsioonide kirjutamist, mis tegelikult on Idrise standardteegis olemas. Näeme, kuidas Idrise listidega fundamentaalsel tasandil opereerida; näeme, et need standardfunktsioonid pole mingi sisseehitatud maagia, ning selle käigus õpime ära mõned lihtsamad standardteegi funktsioonid.
Lisalugemine (vabatahtlik):
Type-Driven development with Idris peatükid:
- Chapter 2. Getting started with Idris, alampeatükid:
- 2.2. Functions: the building blocks of Idris programs, alampeatükid:
- 2.2.3. Writing generic functions: variables in types
- 2.3. Composite types
- 2.3.1. Tuples
- 2.3.2. Lists
- 2.3.3. Functions with lists
- 2.2. Functions: the building blocks of Idris programs, alampeatükid:
Praktikumi ja kodutöö ülesanded
Implementeerige järgnevad funktsioonid vastavalt etteantud tüübile ja ülesandepüstitusele. Pidage meeles, et Moodle automaatkontroll sisaldab teste kõikide selle kodutöö ülesannete jaoks.
Standardteegi funktsioonid
Et nimesid mitte segamini ajada, on kodutöös funktsiooninimedele lisatud ülakoma. S.t. standardteegis on funtksioonid ilma ülakomata.
1. Funktsioon fst'
- paari esimene element
1 2 |
fst' : (a, b) -> a fst' = ?rhs_fst |
Katseta erinevat tüüpi paaridega: näiteks fst' ('x', True)
ja fst' (8, "Tere")
.
2. Funktsioon length'
- listi pikkuse arvutamine
1 2 |
length' : List a -> Int length' = ?rhs_length |
Redutseeri avaldis length' [2, 3, 4]
.
3. Funktsioon +++
- kahe listi konkateneerimine
Standardteegis on listide konkateneerimiseks operaator ++
. (Ülakomad pole operaatorite nimedes lubatud)
1 2 3 |
infixr 7 +++ (+++) : List a -> List a -> List a (+++) = ?rhs_kon |
Redutseeri avaldis [1] +++ [2]
.
4. Funktsioon replicate'
- n-st elemendist x koosneva listi konstrueerimine
1 2 |
replicate' : Int -> a -> List a replicate' = ?rhs_replicate |
replicate' 1 True ==> [True] replicate' 3 False ==> [False, False, False] replicate' 0 True ==> []
5. Funktsioon take'
- listist algusosa võtmine
1 2 |
take' : Int -> List a -> List a take' = ?rhs_take |
Näiteks:
take' 3 [1,2,3,4,5] ==> [1,2,3] take' 5 [2,4] ==> [2,4] take' 0 [1,2,3] ==> []
6. Funktsioon sum'
- listi elementide summa
Kirjutada funktsioon sum'
, mis leiab täisarvude listi summa.
1 2 |
sum' : List Integer -> Integer sum' = ?rhs_sum |
Näiteks:
sum' [1..10] ==> 55 sum' [3, 1, 2] ==> 6 sum' [2] ==> 2 sum' [] ==> 0
Redutseeri avaldis sum' [100, 76, 24]
.
7. Funktsioon drop'
- listi algusosa eemalejätmine
1 2 |
drop' : Int -> List a -> List a drop' = ?rhs_drop |
Näiteks:
drop' 0 [1, 2, 3, 4] ==> [1, 2, 3, 4] drop' 1 [1, 2, 3, 4] ==> [2, 3, 4] drop' 3 [1, 2, 3, 4] ==> [4] drop' 100 [1, 2, 3, 4] ==> []
8. Funktsioon reverse'
- listi ümberpööramine
1 2 |
reverse' : List a -> List a reverse' = ?rhs_reverse |
Näiteks:
reverse' [1, 2, 3] ==> [3, 2, 1] reverse' [True, False] ==> [False, True] reverse' [] ==> []
9. Funktsioon esimesed
Nüüd vaatame mõningaid funktsioone, mida sellisel kujul standardteegis ei ole. (Näiteks, kuna seda saab teha mitme kõrgemat järku funktsiooniga, mida vaatame järgnevates praksides.)
Funktsioon tagastab paaride listi esimesed elemendid (samas järjekorras).
1 2 |
esimesed : List (a, b) -> List a esimesed ps = ?rhs_esimesed |
Näiteks:
esimesed [] ==> [] esimesed [(2, 3), (6, 4), (9, 9)] ==> [2, 6, 9]
10. Funktsioon leidub
Tagastab True
, kui arv leidub listis, muidu False
.
1 2 |
leidub : Integer -> List Integer -> Bool leidub n xs = ?rhs_otsi |
Näiteks:
leidub 3 [1, 2, 3, 4, 5, 6] ==> True leidub 8 [1, 2, 3, 4, 5, 6] ==> False
11. Funktsioon dropLast
Eemaldab listi viimase elemendi.
1 2 |
dropLast : List a -> List a dropLast xs = ?rhs_dropLast |
Näiteks:
dropLast [] ==> [] dropLast [1, 2, 3] ==> [1, 2] dropLast [3, 2, 1, 0] ==> [3, 2, 1]
12. Funktsioon lisa
Lisab tähe sõnesse. Kusjuures nulli või negatiivse indeksiga pannakse täht algusse, suurema indeksiga, kui sõne pikkus, lõppu.
1 2 |
lisa : Int -> Char -> String -> String lisa i x ys = ?rhs_lisa |
Näiteks:
lisa (-1) 'a' "xyz" ==> "axyz" lisa 1 'a' "xyz" ==> "xayz" lisa 3 'a' "xyz" ==> "xyza" lisa 2 'a' "xyz" ==> "xyaz" lisa 400 'a' "xyz" ==> "xyza"
Defineeri abimeetod lisa' : Int -> Char -> List Char -> List Char
.
Sõne ja tähemärkide listi vahel teisendamiseks kasuta funktsioone unpack
ja pack
.
13. Funktsioon arvuta
Väärtustab polünoomi kohal x. Iga listi element (a, n) tähistab polynoomi liidetavat a*x^n.
1 2 |
arvuta : List (Double, Nat) -> Double -> Double arvuta ps x = ?rhs_arvuta |
Näiteks: [(4.0,2),(1.0,1),(30.0,0)]
tähendab 4*x^2 + x + 30
ja
arvuta [(4.0, 2), (1.0, 1), (30.0, 0)] 5 ==> 135.0 arvuta [(4.0, 2), (1.0, 1), (30.0, 0)] 2 ==> 48.0 arvuta [] 5 ==> 0
Selles ülesandes sisseehitatud operaatori ^
kasutamiseks lisa faili päisesse import Data.Monoid.Exponentiation
. Et VScode-is ei oleks import punane, loo käsureal uus fail: touch K2.ipkg
ning faili sisuks kirjuta:
1 2 |
package K2 depends = contrib |
Käsurealt käivita siis nii rlwrap idris2 --find-ipkg K2.idr
või nii rlwrap idris2 -p contrib K2.idr
.
Tärnülesanded
Funktsioon lines
Kirjuta funktsioon lines
, mis võtab sisse sõne ja tagastab sõnede listi,
mille elemendid on sisendi (reavahetusega eraldatud) teksitread.
(Standardteegis on lines
moodulis Data.String
.)
1 2 |
lines : String -> List String lines = ?rhs_lines |
Näiteks:
lines "" ==> [] lines "asfd" ==> ["asfd"] lines "asfd\n" ==> ["asfd"] lines "as\nfd\n" ==> ["as", "fd"] lines "as\nfd\n\n" ==> ["as", "fd", ""]