Ce trebuie sa stiu despre vectorii din Haskell ?

From HaskellWiki
Revision as of 11:42, 16 January 2010 by Ha$kell (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

. Au un tipuri speciale pentru indici

Ca si in alte limbaje nu putem folosi la vectori orice tip de valori pe post de indici. Asa cum nu se pot folosi numerele reale in Pascal, de exemplu.

Exista deci o multime de tipuri acceptate ca indici si ele formeaza o clasa de tipuri speciala.

. Ce proprietati au indicii ?

Un tip poate servi ca indice pentru un vector (care in realitate e stocat liniar) daca:

1. Stiind capetele intervalului de indici putem genera lista finita a acelor indici. - Ceea ce nu se intampla pentru un interval de numere reale. Se spune ca un tip - indice trebuie sa posede, sa i se poata defini o functie range:

range:: (a,a) -> [a]

2.Daca luam o valoare din acest interval de indici , pe baza ei trebuie sa se poata afla al catelea element este adresat - numaratoarea incepind de la zero. Stiti ca in unele cazuri (cum e limbajul Pascal) multimea indicilor elementelor unui vector nu e neaparat [0..n] paote fi [n..m] cu m >=n.

Deci tipul indice va avea / trebuie sa poata avea o functie:

index :: (a,a) -> a -> Int

3.E recomandabil sa existe si o functie de verificare a indexilor incorecti. Ce face ? Verifica daca indicele este in interval si returneza true sau false.

O numeau in engleza: inrange :: (a,a) -> a -> Bool

. Clasa de tipuri Ix

Clasa de tipuri Ix a indicilor contine tipurile ordonabile (din clasa Ord) care au in plus si cele 3 functii de mai sus.

class (Ord a) => Ix a   where
  '''range''':: (a,a) -> [a]
  '''index''' :: (a,a) -> a -> Int
  '''inrange''' :: (a,a) -> a -> Bool

Deci la nevoie orice tip din clasa Ord poate deveni un tip de clasa Ix (adica un index).

. Cum folosim index-ul la accesul la elementele vectorului

Cu operatorul ! In Haskell nu se scrie v[7] ci v ! 7. Dar pentru asta trebuie sa definim vectorul.

. Declaratia de vector

1. Este cu initializare. 2. Trebuie specificat intervalul de indexi sub forma (imin, imax) , deci ca o pereche sau ca la notatia matematica pentru intervalele deschise. (desi aici la noi extremele se includ!). 3. Trebuie data lista de perechi (indice, valoare) pe care va actiona mecanismul de indexare.

Ex: din (1,5) [ (1,1), (2,4) , (3,9) , (4,16) , (5,25) ]

se poate defini vectorul de patrate ale primelor 5 intregi:

patrate = array (1,5) [ (1,1), (2,4) , (3,9) , (4,16) , (5,25) ]

Obs: Cel mai des lista de valori se da in stil implicit, descriptiv, nu explicit, enumerat, si adesea intervalul de indici e folosit iarasi, la descriere. Desi nu e obligatoriu.

Ex: din (1,5) [ (i, i*i) | i <- (1,5) ]

patrate' = array (1,5) [ (i, i*i) | i <- (1,5) ]

. Exemple de acces la elemente

patrate ! 3

9

patrate' 4

16


. Declaratii simplificate

Daca va este dor de declaratiile simple din alte limbaje, cum este Pascal-ul va puteti defini propriile functii de definire la vectori.

Definind, sa zicem:

_Vector f interval = array interval [ (i,f i) | i <- range interval]

Putem de acum incolo sa declaram vectorii asa:

v =_Vector (\x -> x*x) (1,10)

Si bineinteles indexarea ramane la fel:

v ! 10 100

. Exercitiu

Rescrieti functia _Vector astfel ca sa fie apelata cu:

v = _NewVector (\x -> x*x) [1,10]

pentru a obtine vectorul de patrate.

. Biblioteci/Module de importat ?

Importati in program modulul Array. Eventual, daca lucrati cu vectori de caractere (observati ca nu le spunem Stringuri) puteti avea nevoie si de Data.Char. (aici e functia ord, de exemplu.)

. Exemplu de cod pentru primul contact cu vectorii

import Array
import Data.Char

-- array :: Ix a => (a,a) ->        [ (a,b) ] -> Array a b
--                  pereche, lista de perechi indice - valoare 



cuburi = array (1,10) [ (i, i*i*i) | i <- range (1,10) ]

-- aici i-urile provin din acelasi interval (1,10) 


--  cuburi ! 10 
--  1000

vector = array (1,3) [ (1, "ala") , (2,"bala") , (3, "portocala") ]

-- vector 1
-- "ala"

-- vect
-- "bala"

alfabet = array (ord 'a', ord 'z') [ (ord j , j)  | j <- range ('a','z')  ]

---------------------------------------------------------------

_Vector  f interval = array interval  [ (i,f i)  | i <- range interval]

v =_Vector  (\x -> x*x) (1,10)

-- v ! 10
-- 100

. Nu va place operatorul de indexare ! ?

Redefiniti-l astfel ca sa semene cu paranteza []. Se poate obtine ceva mai apropiat de notatia din alte limbaje.

. Bibliografie

Vedeti Gentle subcapitolul 13.1 Index Types. Si urmatoarele subcapitole, sunt ultimele din Gentle.