10 fungsi Built-In
11. Pustaka Standar
11.8 Syarat Syarat dan Pengertian-pengertian
Mulai Dari Q 7.1, script cond.q menyediakan bentuk spesial yang diperlukan untuk menerapkan kedua-duanya berbagai syarat-syarat dan pengertian-pengertian list/stream.
ifelse ~P X Y, when ~P X, unless ~P X
ekspresi-ekspresi bersyarat sederhana
cond CASES, case ~X CASES
banyak cara dan ekspresi-ekspresi pencocokan pola bersyarat
dowhile P X
pembangunan pengulangan sederhana
for CLAUSES X
pengulangan lebih dari lists dan streams
listof X CLAUSES, streamof X CLAUSES
pengertian-pengertian list dan stream
pola yang cocok berlawanan terhadap ekspresi
Semua fungsi-fungsi ini diterapkan sebagai bentuk spesial.
Fungsi ifelse telah disebutkan di Conditional Expressions dan Lambdas. Itu mengembalikan nilai dari X atau Y, tergantung pada apakah argument yang pertama adalah true atau false. Sebagai contoh, di sini bagaimana fungsi faktorial itu dapat diterapkan dengan ifelse:
fac N = ifelse (N>0) (N*fac (N-1)) 1;
Atau, jika anda lebih suka menulis hal ini menggunakan sintak if X then Y else Z yang digambarkan di Conditional Expressions dan Lambdas:
fac N = if N>0 then N*fac (N-1) else 1;
Untuk kasus-kasus di mana anda hanya tertarik dalam melaksanakan salah satu dari bagian, anda dapat juga menggunakan fungsi-fungsi when dan unless yang mengembalikan nilai asli a () jika kondisi cabang tidak dijumpai:
==> def X = 1
==> when (X>0) (writes "positive\n") positive
()
==> unless (X>=0) (writes "negative\n") ()
Seperti yang ditandai, pembangun ini paling bermanfaat ketika digunakan di fungsi-fungsi yang disertai efek samping; kecuali jika pekerjaan-pekerjaan persisnya seperti when, tetapi membalikkan kondisi bagian P. Jika pembangun The if X then Y merupakan gula syntactic untuk when:
==> if X>0 then writes "positive\n" positive
()
Suatu ekspresi bersyarat umum selebihnya juga disediakan, yang mengizinkan anda untuk membeda-bedakan antara satu nomor yang sembarang dari kasus-kasus. Itu mempunyai bentuk:
cond ((P1,X1),(P2,X2),…)
Menggunakan "pengelompokan sintaks" yang digambarkan di Lists, Streams dan Tuples, ini dapat juga ditulis lebih succintly seperti:
cond (P1,X1;P2,X2;…)
bentuk spesial ini kelihatan dan bertindak seperti cond Lisp. itu mengembalikan nilai X yang pertama di mana kondisi P yang sesuai mengevaluasi kepada nilai true. Suatu bagian kondisi dari nilai true dapat digunakan untuk menandai adanya kasus default. Jika tidak ada kasus dibandingkan lalu cond menaikkan suatu perkecualian syserr 8 (catatan bahwa kode error yang
sama juga ditambahkan pada kasus dari suatu kondisi yang tidak berlaku di dalam aturan, cf. Perkecualian Handling).
Kasus bersyarat adalah suatu form yang khusus dari cond di mana ekspresi pertama dari tiap kasus adalah suatu pola P untuk diadu dengan X ekspresi yang diberi:
case X (P1,Y1;P2,Y2;…)
Ekspresi X, yang dilewati nilai, dibandingkan dengan masing-masing dari pola-pola P pada gilirannya, dan secepat suatu pola pembanding ditemukan, nilai Y yang sesuai dikembalikan, dengan variabel-variabel di dalam pola itu harus nilai-nilai yang sesuai yang menggunakan lamda. Suatu pola dari `_' dapat digunakan untuk menandakan kasus default. Jika tidak ada kasus dibandingkan lalu kasus menaikkan suatu perkecualian syserr 8.
Beberapa contoh-contoh:
fac N = cond (N>0, N*fac (N-1); true, 1); sign X = cond (X>0, 1; X<0, -1; true, 0); prod Xs = case Xs ([], 1; [Y|Ys], Y*prod Ys); reply X = case X
("y" , true; "n" , false;
_ , throw "bad reply");
Fungsi dowhile menerapkan suatu pembangun perulangan yang sederhana yang menyimpan ekspresi pengevaluasi ulang di dalam argument yang kedua sepanjang kondisi di dalam argument evaluasi yang pertama bernilai benar. Kedua argument bersifat khusus. Hasil itu adalah selalu (). pembangun ini sungguh-sungguh bisa dipahami hanya dengan ekspresi- ekspresi yang disertai efek samping. Sebagai contoh:
==> def F = fopen "/etc/passwd" "r"
==> dowhile (not feof F) (writes (freads F++"\n"))
Karena fungsi menyediakan suatu maksud untuk mengulangi satu operasi dengan efek samping selain lists dan streams. Dibutuhkan suatu tuple dari ketentuan di dalam argument yang pertama, yang mempunyai bentuk yang sama seperti argument yang kedua dari suatu pengertian lists dan streams (lihat di bawah). Argument yang kedua kemudian dievaluasi karena masing- masing bagian, melaksanakan bagian parameter menggunakan lamda. Hasil itu adalah selalu ().Contoh:
==> for (I in [1..3],J in [1..I]) (write (I,J) || writes " ") (1,1) (2,1) (2,2) (3,1) (3,2) (3,3) ()
Fungsi listof mengizinkan untuk menetapkan daftar nilai-nilai di suatu cara serupa dengan jalan menetapkan yang digambarkan di dalam matematika:
Pembangunan ini juga biasanya disebut suatu daftar pengertian. Untuk kenyamanan, bahasa Q menyediakan syntactic sugar untuk pengertian-pengertian daftar sehingga mereka dapat juga ditulis sebagai berikut:
[X : Y1, Y2, …]
(Catatan bahwa di dalam notasi alternatif script-script ini hanya diizinkan di sisi kanan definisi- definisi persamaan dan variabel, seperti tanda titik dua `:' telah digunakan untuk menandakan tipe penjaga di dalam ekspresi-ekspresi sebelah kiri. Jadi tidak seperti kasus bahwa anda harus memperluas definisi listof yang anda harus menggunakan sintaksis yang pertama dari atas.) Ekspresi-ekspresi Y1, Y2, ... boleh yang manapun yang dipanggil Suatu bagian dari ketentuan atau ketentuan pengandaian. Suatu bagian dari ketentuan adalah satu bentuk ekspresi Z di Zs, menggunakan operator relational di dalam, yang dinyatakan sebagai berikut:
public const (in) X Y @ 2; // relational in operator
Suatu bagian dari ketentuan menetapkan bahwa pola Z harus dibandingkan pada gilirannya kepada masing-masing anggota daftar Zs; hanya nilai-nilai sebanding dengan pola itu yang akan diekstrak, dan peubah bebas di dalam pola itu terikat pada nilai-nilai mereka yang sesuai yang menggunakan lamda. Suatu bagian dari ketentuan dipertimbangkan dari kiri ke kanan, yang berarti bahwa suatu ketentuan boleh mengacu pada setiap variabel diperkenalkan di Suatu bagian dari ketentuan yang sebelumnya.
Ekspresi lain manapun menetapkan suatu anak kalimat pengandaian yang harus mengevaluasi ke suatu nilai kebenaran; hanya unsur-unsur yang akan didaftarkan di mana anak kalimat pengandaian itu dicukupi.
Sebagai contoh, di sini ada suatu fungsi yang menghitung bilangan prima sampai ke suatu N bilangan bulat yang diberi yang menggunakan penyelidikan Erathosthenes. Mencatat pengertian daftar [Y:Y in Xs,Y mod X<>0] di dalam persamaan yang kedua yang digunakan untuk angka- angka ekstrak semua yang tidak dapat dibagi oleh anggota daftar yang pertama (yang selalu suatu yang utama berdasarkan atas konstruksi).
primes N = sieve [2..N];
sieve [X|Xs] = [X|sieve [Y:Y in Xs,Y mod X<>0]]; sieve [] = [];
Here is the same prime sieve algorithm as above, formulated with streams instead of lists. Instead of a list of all primes up to a given limit it simply generates the infinite stream of all prime numbers:
Di sini algoritma ayakan yang utama sama seperti di atas, yang dirumuskan dengan stream dari daftar. Sebagai ganti dari daftar dari semua yang utama sampai ke suatu batasi yang diberi hanya menghasilkan stream tak terhingga dari semua bilangan prima:
primes = sieve {2..};
sieve {X|Xs} = {X|sieve {Y:Y in Xs,Y mod X<>0}};
Akhirnya, sebutan matchp mengembalikan nilai benar jika ekspresi yang diberi sebagai argument yang kedua memenuhi pola sebenarnya di dalam argument yang pertama, untuk nilai
false maka yang lainnya. Fungsi ini digunakan dalam implementasi listof dan streamof, tetapi juga bermanfaat bagi dirinya.