6 Haziran 2012 Çarşamba

Örneklerle Haskell'e küçük bir bakış

        İlk olarak buradan Haskell ile kod geliştirmek için bilgisayarınıza kurmanız gereken platform bilgilerini ve haskell hakkında değerli bilgileri bulabilirsiniz.


        Eğer Haskell'i bilgisayarınıza kurduysanız bir kaç küçük denemeyle başlayabiliriz. Ben linux kullandığım için linux'ta anlatacağım bu arada derleyici olarakta ghc kullanıyorum.
       Öncelikle adettendir diye bir "MerhabaDünya" programı yazalim. (Haskell kodunuzu yazdığınız dosyaların uzantısı .hs dir.)

merhaba.hs

main = putStrLn "Merhaba Dünya"

       Yukarıda kodu linuxta komut satırından ghc merhaba.hs -o merhaba komutuyla derledikten sonra ./merhaba komutu ile çalıştıra bilirsiniz.
      Çalıştırdığınızda görebileceğiniz gibi  kod ekrana "Merhaba Dünya" yazacaktır.
Şimdi kod üzerinde bir kaç şeye dikkat çekmek istiyorum. Fonksiyonel programlama dillerinde adındanda anlaşılacağı gibi herşey fonksiyondur. Kodda gördüğünüz gibi main fonksiyonunu tanımlıyoruz. Diğer programlama dilleri gibi Haskell'dede yürütme(execution) main'den başlar. Haskell'de fonksiyon tanımlamaları :

fonksiyonunAdı parametreleri = fonksiyonunVücudu

şeklindedir. Kodda diğer bir ilgi çekmek istediğim şey "putStrLn" fonksiyonu. "putStrLn" fonksiyonu kendisine parametre olarak verilen string'i ekranda yeni bir satıra basar.
      Şimdi verilen bir sayının asal olup olmadığnı söyleyen bir programın hem C'de hemde Haskell'de yazılmış örneklerini inceyelim. 

asal.hs
isPrime n q = if (n `mod` q) == 0 then 
                False
            else 
                if (q > (floor (sqrt (fromIntegral n)))) then 
                    True 
                else 
                    isPrime n (q+1)  
main = do{  putStrLn "Bir Sayı giriniz: ";
            x <- readLn;
            if (isPrime x 2) then
                putStrLn "Asal"
            else 
                putStrLn "Asal DEĞİL";
        }

Yukarıdaki Haskell kodunda 2 tane fonksiyonumuz var. isPrime fonksiyonu sayesinde kullanıcıdan aldığımız sayıyı kare köküne kadar olan bütün sayılara bölmeye çalışıyoruz. Eğer aldığımız sayı denediğimiz sayılardan herhangi birine bölünürse, sayı asal olmadığı için fonksiyonumuzun değeri False oluyor. Eğer sayı kendi kare köküne kadar olan hiç bir sayıya bölünmezse sayımız asal olduğu için fonksiyonumuzun değeri True oluyor. Farkettiyseniz isPrime fonksiyonundan main fonksiyonuna değer dönerken 'return' tarzı bir bildiri kullanmadım. Matematikteki fonksiyonları düşünün f(x)=x+3 dediğimiz zaman aslında bu fonksiyon bize birşey dönmez değilmi. Oda aslında bir sayıdır tek farkı değerinin bizim verdiğimiz x'e bağlı olması. Tabiki bu Haskell'de 'return' yok anlamına gelmiyor. İlerleyen zamanlarda bu konuya daha derinlemesine bakma şansı bulucaz. Şimdi aynı koda birde C'de bakalım:

asal.c
#include 
#include 
int isPrime(int n){
    int i;
    for(i=2 ; i<=sqrt(n) ; i++)
        if( n % i == 0)
            return 0;
    return 1;
}
int main(){
    int n;
    printf("Bir sayi giriniz:");
    scanf("%d",&n);
    if( isPrime( n ) )
        printf("Asal\n");
    else
        printf("Asal DEGIL\n");
    return 0;
}

       Fonksiyonel programlama dillerinde değişken tanımlama olmadığından  durum diye bir olgu yoktur. Mesela yukaridaki C kodunda isPrime fonksiyonunda tanımlanmış olan 'i' değişkeni o C fonksiyonu için bir durum göstergesidir. 'i' her değiştiğinde fonksiyonun durumuda değişir.
       C'deki isPrime fonksiyonundaki bir farklılıkta tam sayı (integer) 'i' değişkeniyle 'sqrt' fonksiyonunun döndüğü ondalıklı(float) sayı arasında bir kıyaslama  yapabilmemiz. Haskell'de farkedeceğiniz üzere aşşağıdaki kodu kullanarak kıyaslamadan önce sayımızı tamsayıya çevirdik.

(floor (sqrt (fromIntegral n)))

Tam sayıya çevirmeseydik kıyaslama işlemini gerçekleştirmezdik çünkü Haskell "strongly typed" bir dildir. Yani her hangi bir işlem yaparken kullandığınız değişkenlerin tipleri aynı olmak zorundadır.
        Son olarak yukardakiyne aynı işi yapan bir Haskell kodu(kodu ilerleyen zamanlarda açıklayacağım):

main = do { putStrLn "Bir sayı giriniz:";
            x <- readLn;
            let dividerList = [n| n<-[2..x-1], x `mod` n == 0] 
            in if (length dividerList)==0 then
                    putStrLn "Asal"
                else
                    putStrLn "Asal değil"        
        }




Hiç yorum yok:

Yorum Gönder