Haskell Dili: Funksional Proqr....md
---
title: "Haskell Dili: Funksional Proqramlaşdırmaya Giriş"
read_time: 5 dəq
date: 12 fev 2026
categories: [ Proqram Dilləri ]
---

Haskell Dili: Funksional Proqramlaşdırmaya Giriş

“Dil bizim necə düşündüyümüzü formalaşdırır və nə haqqında düşünə biləcəyimizi müəyyən edir”.

Benjamin Lee Whorf-un bu fikri proqramlaşdırma dünyasında bəlkə də ən çox Haskell dilinə yaraşır. Deyə bilərəm ki, Haskell sadəcə yeni bir sintaksis öyrənmək deyil, həm də hesablama prosesinə tamamilə fərqli bir rakursdan baxmaqdır. Əgər siz dəyişənlərin daim dəyişdiyi, dövrlərin hər addımda vəziyyəti yenilədiyi dünyadan gəlirsinizsə, Haskell sizə başlanğıcda bir az sirli, lakin inanılmaz dərəcədə güclü kainat vəd edir.

Haskell-in Mahiyyəti: Funksional Yanaşma

Haskell təmiz funksional proqramlaşdırma (FP) dilidir. Yəni burada biz kompüterə addım-addım nə edəcəyini (imperativ proqramlaşdırma) demirik, sadəcə problemin özünü (deklarativ proqramlaşdırma) təsvir edirik. FP dili proqramçını məlumatlara bütöv bir obyekt kimi baxmağa sövq edir, onu hissə-hissə emal etməyə yox.

Haskell-in sənayedəki tətbiqi də az deyil. Facebook-un Haxl kitabxanasından tutmuş, Cardano kimi kriptovalyuta platformalarına, Barclays və Standard Chartered kimi maliyyə nəhənglərinə qədər bir çox yer daxili sistemlərin təhlükəsizliyi üçün bu dili seçir. Edinburgh, Oxford və Cambridge kimi nüfuzlu universitetlərdə proqramlaşdırmanın ilk olaraq Haskell ilə öyrədilməsi, tələbələri ən başından analitik düşünməyə alışdırır.

Əsas Xüsusiyyətlər: Gecikmiş Hesablama və Güclü Tiplər

Haskell-i fərqləndirən bir neçə məqam var:

  1. Güclü Tip sistemi: Haskell-də hər bir dəyərin bir tipi var (v :: t). Məsələn, 42 :: Int və ya sqrt :: Float -> Float. Bu tip sistemi proqram hələ işə düşmədən bir çox xətaları tutur.
  2. Gecikmiş hesablama: Haskell bir ifadənin nəticəsinə ehtiyac duyulmayana qədər onu hesablamır. Bu xüsusiyyət bizə sonsuz siyahılarla işləmək imkanı verir. Məsələn, [0..] yazaraq sıfırdan sonsuzluğa qədər uzanan bir siyahı yarada bilərsiniz, lakin Haskell ondan yalnız sizə lazım olan hissəni götürəcək.
  3. Rekursiya: Haskell-də for və ya while dövrləri yoxdur. Hər şey rekursiya üzərində qurulub. Bir siyahını emal etmək üçün onu boş siyahı [] və ya “baş” və “quyruq” hissələrinə (x:xs) (x -> head & xs -> tail) parçalayırıq.

Tip Təhlükəsizliyi və Cəbri Məlumat Tipləri

Mənim üçün Haskell-in ən gözəl tərəfi **cəbri məlumat tipi**dir (ADT)[^burada “cəbri” sözü bu tiplərin üzərində apa bildiyimiz riyazi əməllərdən gəlir]. Biz öz dünyamızı çox dəqiq modelləşdirə bilirik. Məsələn, bir proqramda dəyərin olub-olmaması (null problemi) bir çox dildə işgəncədir. Haskell-də isə Maybe a tipi var: ya Just a (dəyər var), ya da Nothing (dəyər yoxdur). Bu, sizi hər ehtimalı nəzərə almağa məcbur edir və proqramın gözlənilmədən çökməsinin qarşısını alır.

Həmçinin, typedata açar sözləri ilə yeni tiplər yarada, hətta məntiqi ifadələr və ya riyazi ifadə ağacları kimi mürəkkəb strukturlar qura bilərik.

Dərin Riyazi və Tarixi Köklər

Haskell-in gücü yalnız dizayndan yox, dərin elmi köklərdən gəlir.

  1. Lambda hesablaması: Haskell-in nəzəri əsası lambda hesablamasıdır. Bu sistem 1930-cu illərdə Alonzo Church tərəfindən yaradılıb. \x -> x * 2: Buradakı \ simvolu əslində λ (lambda) hərfinin klaviatura versiyasıdır.

  2. Karriləmə və Funksional Məntiq: Haskell-də funksiyalar karriləmə prinsipi ilə işləyir. Funksiyanın işləyişi belədir: add :: Int -> Int -> Int Əslində isə: Int -> (Int -> Int) Funksiyaların arqumentlərini hissə-hissə ötürmək texnikası “karriləmə” adlanır.

    Maraqlı Fakt: Bu gün Haskell-də təbii qəbul etdiyimiz “karriləmə” ideyası yarananda ortada nə müasir proqramlaşdırma dilləri var idi, nə də kompüterlər. Bu yanaşma XX əsrin əvvəllərində insanın məntiqi düşüncə tərzini modelləşdirmək üçün irəli sürülmüşdü. Dilin adını aldığı Haskell Curry bu fikri sonralardan sistemləşdirsə də, konseptin əsasları Moses SchönfinkelGottlob Frege kimi alimlərin işlərinə dayanır. Bu səbəbdən Haskell-də yazılan kod çox vaxt riyazi sübuta bənzəyir.

  3. Peano və Rekursiv Struktur: Haskell-in düşüncə modeli riyaziyyatdan gəlir. Məsələn, natural ədədlər belə modelləşdirilə bilir: data Nat = Zero | Succ Nat. Bu struktur Giuseppe Peano-nun aksiomlarına əsaslanır.

Praktik Nümunələr:

Gəlin Haskell-də kodun necə göründüyünü iki nümunə ilə araşdıraq.

  1. Tam Funksional Üslub (Karriləmə və Kompozisiya): Burada funksiyaları silsilə şəklində birləşdirilir. Bu yanaşma Haskell Curry-nin şərəfinə adlandırılan “karriləmə” prinsipini — yəni hər funksiyanın əslində bir arqument alaraq yeni bir funksiya qaytarmasını nümayiş etdirir.
-- Siyahıdakı müsbət ədədlərin kvadratlarının cəmi
sumSqPositive :: [Int] -> Int
sumSqPositive = foldr (+) 0 . map (^ 2) . filter (> 0)

Burada . simvolu funksiya kompozisiyasını bildirir: məlumat filtrdən keçir, map olunur və sonda foldr ilə toplanır. Bu kompozisiya məktəb riyaziyyatında öyrəndiyimiz f(g(h(x))) kimi bir ifadəyə bənzəyir.

  1. ADT ilə Strukturlaşdırılmış Yanaşma: Bu üslub OOP-dəki siniflərə bənzəyir, lakin daha zəngindir.
data Shape = Circle Float | Rect Float Float deriving (Show)

area :: Shape -> Float
area (Circle r) = pi * r^2
area (Rect w h) = w * h

Bu kodda şablon uyğunlaşdırma istifadə olunur; Haskell avtomatik olaraq fiqurun tipini təyin edir.

Çətinliklər və Yayğın Səhvlər

Əlbəttə, hər şey mükəmməl deyil. Yeni başlayanlar üçün ən böyük çətinliklərdən biri IO (Giriş-Çıxış)monadlar mövzusudur. Haskell “təmiz” dildir, yəni funksiyalar yan təsir göstərməməlidir. Bəs onda ekrana necə nəsə çap edək? Burada Haskell main :: IO () vasitəsilə “təmiz” dünya ilə “çirkli” real dünya arasında körpü yaradır.

Effektivlik də vacibdir. Məsələn, siyahıları birləşdirərkən (++) onları soldan deyil, sağdan qruplaşdırmaq (məsələn, foldr vasitəsilə) proqramın sürətini O(m^2 _ n)-dən O(m _ n)-ə qədər artıra bilər.

Şəxsi Təcrübə və Öyrəndiklərim

Haskell ilə ilk tanış olduğumda “dəyişənsiz proqram olar?” deyə düşünmüşdüm. Lakin zamanla anladım ki, dəyişənlərin vəziyyətini izləmək əvəzinə, məlumatın axınını (məlumat axını) düşünmək zehni daha az yorur. Haskell öyrənmək mənə digər dillərdə (Java, Python və s.) daha təmiz və xətasız kod yazmağı öyrətdi.

Yeni Başlayanlara Tövsiyələr

  1. Kiçik addımlarla başlayın: Əvvəlcə siyahılar və rekursiyanı mənimsəyin.
  2. GHCi-dən bol istifadə edin: GHC Hasell üçün kompilyatordur. Onun interaktiv versiyası GHCi adlanır. Burada “canlı” nümunələr yoxlayaraq funksional ideyalarımızı təsdiq edə bilərik. Bu interaktiv mühit sizin ən yaxın dostunuzdur, hər n kiçik funksiyanı orada yoxlayın.
  3. Tipləri yaxşı öyrənin: Əgər kodunuz kompilyasiya olunmursa, çox gümman ki, tiplərdə uyğunsuzluq var. Haskell-in xəta mesajlarını oxumağı öyrənin.
  4. Monadlara fokuslanmayın: Başlanğıcda monadların riyazi nəzəriyyəsini deyil, onların praktik olaraq proqramın axınını necə idarə etdiyini (məsələn, do notasiyası ilə) öyrənin.

Yekun

Funksional proqramlaşdırmaya yeni başlayırsınızsa Haskell sizin üçün sadəcə bir dil deyil, bir az qəribə, bir az da maraqlı bir təcrübə olacaq. Amma Haskell kimi dillər problemlərə daha diqqətlə yanaşmağı, yazdığın kodun arxasında nə baş verdiyini düşünməyi vadar edir. Bu da uzun müddətdə proqramlaşdırmaya baxışını dəyişir.

// terminlər

axın stream
Məlumatın hissə-hissə və davamlı şəkildə ötürülməsi (və ya icra edilən thread/axın kontekstində fərqli tapşırıq zolağı).
cəbri məlumat tipi algebraic data type
Tipi bir neçə konstruktorun cəmi və ya hasili kimi modelləşdirən tip yanaşması.
↗ Ətraflı
deklarativ proqramlaşdırma declarative programming
Nəticənin necə yox, nə olmalı olduğunu ifadə edən proqramlaşdırma yanaşması.
↗ Ətraflı
funksional proqramlaşdırma functional programming
Hesablamanı əsasən funksiyaların birləşməsi kimi modelləşdirən paradiqma.
↗ Ətraflı
funksiya kompozisiyası function composition
Bir funksiyanın nəticəsini digər funksiyanın girişinə ötürərək yeni funksiya yaratma.
↗ Ətraflı
gecikmiş hesablama lazy evaluation
İfadələri yalnız ehtiyac olduqda qiymətləndirmək prinsipi.
↗ Ətraflı
imperativ proqramlaşdırma imperative programming
Kompüterə addım-addım hansı əməliyyatları etməli olduğunu bildirən yanaşma.
↗ Ətraflı
karriləmə currying
Çoxarqumentli funksiyanı bir arqument qəbul edən funksiyalar zəncirinə çevirmə üsulu.
↗ Ətraflı
kitabxana library
Təkrar istifadə oluna bilən hazır kod modulları toplusu.
↗ Ətraflı
kompilyator compiler
Mənbə kodunu icradan əvvəl maşın koduna və ya aralıq koda çevirən proqram.
↗ Ətraflı
lambda hesablaması lambda calculus
Funksiyaların hesablanmasını formal modelləşdirən riyazi sistem; funksional dillərin nəzəri bazasıdır.
↗ Ətraflı
monad monad
Funksional proqramlaşdırmada yan təsirləri və hesablama kontekstini idarə edən abstraksiya.
↗ Ətraflı
obyekt-yönümlü proqramlaşdırma object-oriented programming
Məlumatı və davranışı obyektlər daxilində birləşdirən proqramlaşdırma paradiqması.
↗ Ətraflı
rekursiya recursion
Funksiyanın nəticəyə çatana qədər özünü çağırması üsulu.
↗ Ətraflı
sintaksis syntax
Proqramlaşdırma dilinin qrammatik qaydaları — kodun necə yazılmalı olduğunu müəyyən edən struktur.
↗ Ətraflı
şablon uyğunlaşdırma pattern matching
Məlumatın quruluşuna görə avtomatik parçalanması və uyğun kod budağının seçilməsi.
↗ Ətraflı
tip sistemi type system
Proqramdakı dəyərlərə tip təyin edərək xətaları kompilyasiya zamanı aşkar edən qaydalar toplusu.
↗ Ətraflı
yan təsir side effect
Funksiyanın nəticə qaytarmaqdan əlavə kənar vəziyyəti dəyişdirən davranışı.
↗ Ətraflı

// şərhlər