diff options
-rw-r--r-- | tr-tr/fsharp-tr.html.markdown | 630 |
1 files changed, 630 insertions, 0 deletions
diff --git a/tr-tr/fsharp-tr.html.markdown b/tr-tr/fsharp-tr.html.markdown new file mode 100644 index 00000000..d88e2594 --- /dev/null +++ b/tr-tr/fsharp-tr.html.markdown @@ -0,0 +1,630 @@ +--- +language: F# +contributors: + - ["Scott Wlaschin", "http://fsharpforfunandprofit.com/"] +translators: + - ["Mustafa Zengin", "http://zengin.github.com/"] +filename: learnfsharp-tr.fs +--- + +F# fonksiyonel ve nesne yönelimli, genel amaçlı bir programlama dilidir. Bedava ve açık kaynaklıdır ve Linux, Mac, Windows ve dahasında çalışır. + +Hataları derleme zamanında yakalayan çok güçlü bir tip sistemine sahiptir, ancak tip çıkarımı yaptığından dinamik bir dil gibi görünür. + +F#'ın söz dizimi C-stili dillerden farklıdır: + +* Küme parantezi kod bloklarını ayırmak için kullanılmaz. Bunun yerine Python'da olduğu gibi girinti kullanılır. +* Parametreleri birbirinden ayırmak için virgül yerine boşluk karakteri kullanılır. + +Aşağıdaki kodu denemek istiyorsanız, [tryfsharp.org](http://www.tryfsharp.org/Create)'a gidin be interaktif REPL'e kodu yapıştırın. + +```csharp + +// tek satır yorumlar ikili bölme işareti ile başlar +(* çok satırlı yorumlar ( * . . . * ) ikilisini kullanır + +-çok satırlı yorumun sonu- *) + +// ================================================ +// Temel Söz Dizimi +// ================================================ + +// ------ "Değişkenler" (tam da değil) ------ +// "let" anahtar kelimesi (değişmez) değer tanımlar +let tamsayım = 5 +let ondalığım = 3.14 +let stringim = "merhaba" // tip bilgisi olmamasına dikkat + +// ------ Listeler ------ +let ikidenBeşe = [2; 3; 4; 5] // Köşeli parantezler listeleri oluşturur, + // değerler ise noktalı virgülle ayrılır. +let birdenBeşe = 1 :: ikidenBeşe // :: yeni birinci elemanı olan bir liste oluşturur. +// Sonuç: [1; 2; 3; 4; 5] +let sıfırdanBeşe = [0; 1] @ ikidenBeşe // @ iki listeyi birbirine ekler. + +// ÖNEMLİ: virgüller hiçbir zaman ayraç olarak kullanılmaz, sadece noktalı virgüller! + +// ------ Fonksiyonlar ------ +// "let" anahtar kelimesi isimlendirilmiş fonksiyonları da tanımlar. +let kare x = x * x // Parantez kullanılmadığına dikkat. +kare 3 // Şimdi fonksiyonu uygulayın. Yine parantez yok. + +let topla x y = x + y // topla (x,y) kullanmayın! Bu tamamen başka bir anlama geliyor. +topla 2 3 // Şimdi fonksiyonu uygulayın. + +// çok satırlı bir fonksiyon tanımlamak için sadece girinti kullanın. Noktalı virgül gerekmez. +let çiftler liste = + let çiftMi x = x % 2 = 0 // "çiftMi"yi alt fonksiyon olarak tanımlayın + List.filter çiftMi liste // List.filter 'boolean bir fonksiyon' ve + // 'üzerinde çalışılacak bir liste' parametrelerinden oluşan + // bir kütüphane fonksiyonu + +çiftler birdenBeşe // Şimdi fonksiyonu uygula. + +// Parantezleri önceliği netleştirmek için kullanabilirsiniz. Bu örnek +// "map"i önce iki argümana, sonra sonuç üzerinde "ekle" uyguluyor. +// Parantezler olmasaydı, "List.map" List.sum'ın ilk argümanı olurdu. +let yüzeKadarKarelerinToplamı = + List.sum ( List.map kare [1..100] ) + +// Bir operasyonun sonucunu bir sonrakine "|>" kullanarak besleyebilirsin. +// Veri beslemek F#'ta UNIX'te olduğu gibi yaygındır.. + +// Burada yüzeKadarKarelerinToplamı fonksiyonunun veri beslemeyle yazılmış hali var: +let veriBeslemeyleYüzeKadarKarelerinToplamı = + [1..100] |> List.map kare |> List.sum // "kare" önceden tanımlanmıştı + +// Lambda'ları (anonim fonksiyonları) "fun" anahtar kelimesiyle tanımlayabilirsin +let funlaYüzeKadarKarelerinToplamı = + [1..100] |> List.map (fun x -> x * x) |> List.sum + +// F#'ta "return" anahtar kelimesi yoktur. Bir fonksiyon +// her zaman son kullanılan ifadeyi döndürür. + +// ------ Kalıp eşleştirme ------ +// Match..with.. çok güçlü bir case/switch türevidir. +let basitKalıpEşleştirme = + let x = "a" + match x with + | "a" -> printfn "x a'dır" + | "b" -> printfn "x b'dir" + | _ -> printfn "x başka bir şeydir" // alt çizgi bütün kalıplarla eşleşir + +// F# varsayılan olarak null'lara izin vermez -- Option tipini kullanıp +// kalıp eşleştirme yapmalısın. +// Some(..) ve None, Nullable tipler gibidir. +let geçerliDeğer = Some(99) +let geçersizDeğer = None + +// Bu örnekte, match..with "Some" ve "None"la eşleştirme yapıyor, +// ve ayrıca "Some" içerisindeki değeri de çıkarıyor. +let optionKalıpEşleştirme input = + match input with + | Some i -> printfn "input is an int=%d" i + | None -> printfn "input is missing" + +optionKalıpEşleştirme geçerliDeğer +optionKalıpEşleştirme geçersizDeğer + +// ------ Yazdırma ------ +// printf/printfn fonksiyonları C#'taki +// Console.Write/WriteLine fonksiyonlarına benzer. +printfn "Bir tamsayı %i, bir ondalık %f, bir boolean %b yazdırma" 1 2.0 true +printfn "Bir string %s, ve jenerik bir tip %A" "merhaba" [1; 2; 3; 4] + +// sprintf/sprintfn fonksiyonları ise veriyi string'e +// çevirmek içindir, C#'taki String.Format gibi. + +// ================================================ +// Fonksiyonlar hakkında dahası +// ================================================ + +// F# gerçek bir fonksiyonel dildir. Fonksiyonlar birinci +// sınıf varlıklardır ve güçlü yapılar oluşturmak için +// birleştirilebilirler. + +// Modüller fonksiyonları gruplamak için kullanılır. +// Her bir modül için girinti gerekir. +module FonksiyonOrnekleri = + + // Temel bir ekleme fonksiyonu tanımla + let topla x y = x + y + + // Bir fonksiyonun temel kullanımı + let a = topla 1 2 + printfn "1 + 2 = %i" a + + // Parametreleri kaynaklamak için parçalı uygulama + let kırkİkiEkle = topla 42 + let b = kırkİkiEkle 1 + printfn "42 + 1 = %i" b + + // Fonksiyonları birleştirmek için kompozisyon + let birEkle = topla 1 + let ikiEkle = topla 2 + let üçEkle = birEkle >> ikiEkle + let c = üçEkle 7 + printfn "3 + 7 = %i" c + + // Yüksek dereceli fonksiyonlar + [1..10] |> List.map üçEkle |> printfn "yeni liste: %A" + + // Fonksiyonlar listesi ve dahası + let altıEkle = [birEkle; ikiEkle; üçEkle] |> List.reduce (>>) + let d = altıEkle 7 + printfn "1 + 2 + 3 + 7 = %i" d + +// ================================================ +// Listeler ve kolleksiyonlar +// ================================================ + +// Üç çesit sıralı fonksiyon vardır: +// * Listeler en temel değiştirilemez kolleksiyonlardır. +// * Diziler değiştirilebilir ve gerektiğinde daha verimlidirler. +// * Seriler tembel (lazy evaluation) ve sonsuzdurlar (Enumeratörler gibi). +// +// Değiştirilmez map'ler ve kümeler ve bütün .NET kolleksiyonları +// diğer kolleksiyon türleridir. + +module ListeÖrnekleri = + + // listeler köşeli parantez kullanır + let liste1 = ["a"; "b"] + let liste2 = "c" :: liste1 // :: başa eleman ekler + let liste3 = liste1 @ liste2 // @ listeleri birbirine ekler + + // Liste comprehension'ları (jeneratörler olarak da bilinir) + let kareler = [for i in 1..10 do yield i * i] + + // asal sayı jeneratörü + let rec elek = function + | (p::xler) -> p :: elek [ for x in xler do if x % p > 0 then yield x ] + | [] -> [] + let asallar = elek [2..50] + printfn "%A" asallar + + // Listelerle kalıp eşleştirme + let listeEşleyici liste = + match liste with + | [] -> printfn "liste boş" + | [birinci] -> printfn "listede sadece bir eleman var: %A " birinci + | [birinci; ikinci] -> printfn "liste: %A ve %A" birinci ikinci + | _ -> printfn "listede ikiden fazla eleman var" + + listeEşleyici [1; 2; 3; 4] + listeEşleyici [1; 2] + listeEşleyici [1] + listeEşleyici [] + + // Listeleri kullanarak recursion + let rec ekle liste = + match liste with + | [] -> 0 + | x::xler -> x + ekle xler + ekle [1..10] + + // ----------------------------------------- + // Standart kütüphane fonksiyonları + // ----------------------------------------- + + // map + let üçEkle x = x + 3 + [1..10] |> List.map üçEkle + + // filter + let çift x = x % 2 = 0 + [1..10] |> List.filter çift + + // ve dahası -- dökümantasyona bakınız + +module DiziÖrnekleri = + + // Diziler köşeli parantezle birlikte çubuk karakterini kullanır + let dizi1 = [| "a"; "b" |] + let birinci = dizi1.[0] // nokta kullanarak indeks erişimi + + // Diziler için kalıp eşleştirme listlerle aynıdır + let diziEşleştirici liste = + match liste with + | [| |] -> printfn "dizi boş" + | [| birinci |] -> printfn "dizide sadece bir eleman var: %A " birinci + | [| birinci; ikinci |] -> printfn "dizi: %A ve %A" birinci ikinci + | _ -> printfn "dizide ikiden fazla eleman var" + + diziEşleştirici [| 1; 2; 3; 4 |] + + // Listede olduğu gibi kütüphane fonksiyonları + + [| 1..10 |] + |> Array.map (fun i -> i + 3) + |> Array.filter (fun i -> i % 2 = 0) + |> Array.iter (printfn "değer: %i. ") + + +module SeriÖrnekleri = + + // seriler kıvrık parantez kullanır + let seri1 = seq { yield "a"; yield "b" } + + // seriler yield'ı kullanabilir + // ve alt seriler barındırabilir + let garip = seq { + // "yield" bir eleman ekliyor + yield 1; yield 2; + + // "yield!" bütün bir alt seriyi ekliyor + yield! [5..10] + yield! seq { + for i in 1..10 do + if i % 2 = 0 then yield i }} + // test + garip |> Seq.toList + + + // Seriler "unfold" kullanılarak oluşturulabilir + // Fibonacci serisi örneği + let fib = Seq.unfold (fun (birinci,ikinci) -> + Some(birinci + ikinci, (ikinci, birinci + ikinci))) (0,1) + + // test + let fib10 = fib |> Seq.take 10 |> Seq.toList + printf "ilk 10 fibonacci sayısı: %A" fib10 + + +// ================================================ +// Veri Tipleri +// ================================================ + +module VeriTipiÖrnekleri = + + // Bütün veriler varsayılan olarak değiştirilemezdir. + + // -- Tuple oluşturmak için virgül kullan + let ikiliTuple = 1, 2 + let üçlüTuple = "a", 2, true + + // Tuple'lar çabuk ve kolay anonim tiplerdir. + // paketi açmak için kalıp eşleştirme kullan + let x, y = ikiliTuple // x = 1, y = 2 + + // ------------------------------------ + // Record tipi isimlendirilmiş alanlara sahiptir + // ------------------------------------ + + // "type" ile kıvrık parantezleri record tipi oluşturmak için kullan + type Kişi = {Ad:string; Soyad:string} + + // "let" ile kıvrık parantezi record tipi oluşturmak için kullan + let kişi1 = {Ad="Falanca"; Soyad="Kişi"} + + // paketi açmak için kalıp eşleştirme kullan + let {Ad = Ad} = kişi1 // birinci="John" + + // ------------------------------------ + // Union tipleri (değişkenler olarak da bilinir) birden fazla + // seçeneğe sahiptir. Belli bir zamanda sadece bir tanesi geçerlidir. + // ------------------------------------ + + // "type" ile çubuk karakterini union tipi tanımlamak için kullan + type Sıcaklık = + | Santigrat of float + | Fahrenhayt of float + + // Seçeneklerden birini kullan + let derece1 = Fahrenhayt 98.6 + let derece2 = Santigrat 37.0 + + // Paketi açmak için bütün seçenekler üzerinde kalıp eşleştirme kullan + let dereceYazdır = function + | Santigrat t -> printfn "%f C" t + | Fahrenhayt t -> printfn "%f F" t + + dereceYazdır derece1 + dereceYazdır derece2 + + // ------------------------------------ + // Yinelgen (Recursive) tipler + // ------------------------------------ + + // Tipler alt sınıflar oluşturmadan karmaşık şekillerde + // yinelgen olarak birleştirilebilirler. + type Çalışan = + | İşçi of Kişi + | Yönetici of Çalışan list + + let falancaKişi = {Ad="Falanca"; Soyad="Kişi"} + let işçi = İşçi falancaKişi + + // ------------------------------------ + // Tipleri Kullanarak Modelleme + // ------------------------------------ + + // Union tipleri bayrak kullanmadan durum modelleme için harikadır. + type EpostaAdresi = + | GeçerliEpostaAdresi of string + | GeçersizEpostaAdresi of string + + let epostaGöndermeyiDene eposta = + match eposta with // kalıp eşleştirme kullan + | GeçerliEpostaAdresi adres -> () // gönder + | GeçersizEpostaAdresi adres -> () // gönderme + + // Union tiplerin record tiplerle birleşimi + // domain driven design için iyi bir temel oluşturur. + // Domain'i yansıtan yüzlerce ufak tip oluşturabilirsiniz. + + type Ürün = { ÜrünKodu: string; Miktar: int } + type Ödeme = Ödeme of float + type AktifSepetVerisi = { ÖdenmemişÜrünler: Ürün list } + type ÖdenmişSepetVerisi = { ÖdenmişÜrünler: Ürün list; Ödeme: Ödeme} + + type AlışverişSepeti = + | BosSepet // veri yok + | AktifSepet of AktifSepetVerisi + | ÖdenmişSepet of ÖdenmişSepetVerisi + + // ------------------------------------ + // Tipler için içgüdüsel davranış + // ------------------------------------ + + // Çekirdek tipler kendinden çok kullanışlı özelliklere sahiptir + // Ek kodlama gerektirmez + // * Değişmezlik + // * Debug ederken yazdırma + // * Eşitlik ve kıyaslama + // * Serialization + + // %A kullanarak yazdırma + printfn "ikiliTuple=%A,\nKişi=%A,\Sıcaklık=%A,\nÇalışan=%A" + ikiliTuple kişi1 derece1 işçi + + // Eşitlik ve kıyaslama içgüdüseldir. + // İskambil kartlarıyla bir örnek + type Simge = Sinek | Karo | Maça | Kupa + type Sıra = İki | Üç | Dört | Beş | Altı | Yedi | Sekiz + | Dokuz | On | Bacak | Kız | Papaz | As + + let el = [ Sinek, As; Kupa, Üç; Kupa, As; + Maça, Bacak; Karo, İki; Karo, As ] + + // Sıralama + List.sort el |> printfn "artarak dizilen el: %A" + List.max el |> printfn "en yüksek kart: %A" + List.min el |> printfn "en düşük kart: %A" + + +// ================================================ +// Aktif Kalıplar +// ================================================ + +module AktifKalıpÖrnekleri = + + // F# "aktif kalıplar" denen bir kalıp eşleştirmeye sahiptir. + // Kalıplar dinamik bir şekilde tespit edilip eşleştirilebilir. + + // Aktif kalıplar için söz dizimi (| ... |) şeklindedir + + // Örneğin, karakter tiplerini eşleyen bir "aktif" kalıp tanımlayın... + let (|Rakam|Harf|Boşluk|Diğer|) karakter = + if System.Char.IsDigit(karakter) then Rakam + else if System.Char.IsLetter(karakter) then Harf + else if System.Char.IsWhiteSpace(karakter) then Boşluk + else Diğer + + // ... daha sonra eşleme mantığı çok daha net yapmak için bunu kullanın + let karakterYazdır karakter = + match karakter with + | Rakam -> printfn "%c bir rakamdır" karakter + | Harf -> printfn "%c bir harftir" karakter + | Boşluk -> printfn "%c bir boşluktur" karakter + | _ -> printfn "%c başka bir şeydir" karakter + + // Bir liste yazdırma + ['a'; 'b'; '1'; ' '; '-'; 'c'] |> List.iter karakterYazdır + + // ----------------------------------- + // Aktif Kalıpları Kullanarak FizzBuzz + // ----------------------------------- + + // Parçalı eşleşen kalıplar da oluşturabilirsiniz + // Tanımda alt çizgi karakterini kullanın ve eşleşince Some döndürün. + let (|ÜçünKatı|_|) i = if i % 3 = 0 then Some ÜçünKatı else None + let (|BeşinKatı|_|) i = if i % 5 = 0 then Some BeşinKatı else None + + // Ana fonksiyon + let fizzBuzz i = + match i with + | ÜçünKatı & BeşinKatı -> printf "FizzBuzz, " + | ÜçünKatı -> printf "Fizz, " + | BeşinKatı -> printf "Buzz, " + | _ -> printf "%i, " i + + // test + [1..20] |> List.iter fizzBuzz + +// ================================================ +// Sadelik +// ================================================ + +module AlgoritmaÖrnekleri = + + // F#'ın sinyal/gürültü oranı yüksektir, dolayısıyla + // kod algoritmayla hemen hemen aynı görünür. + + // ------ Örnek: karelerToplami fonksiyonunu tanımla ------ + let karelerToplamı n = + [1..n] // 1) 1'den n'e kadar bütün sayıları al + |> List.map kare // 2) hepsinin karesini al + |> List.sum // 3) sonuçları topla + + // test + karelerToplamı 100 |> printfn "kareler toplamı = %A" + + // ------ Örnek: bir sıralama fonksiyonu tanımla ------ + let rec sırala liste = + match liste with + // Liste boşsa + | [] -> + [] // boş listeyi döndür + // Liste boş değilse + | ilkEleman::diğerElemanlar -> // İlk elemanı al + let küçükElemanlar = // Daha küçük elemanları + diğerElemanlar // diğerlerinden ayır + |> List.filter (fun e -> e < ilkEleman) + |> sırala // ve sırala + let büyükElemanlar = // Daha büyük elemanları + diğerElemanlar // diğerlerinden ayır + |> List.filter (fun e -> e >= ilkEleman) + |> sırala // ve sırala + // 3 parçayı birbirine ekle ve listeyi döndür + List.concat [küçükElemanlar; [ilkEleman]; büyükElemanlar] + + // test + sırala [1; 5; 23; 18; 9; 1; 3] |> printfn "Sırala = %A" + +// ================================================ +// Eşzamansız kod +// ================================================ + +module EşzamansızÖrneği = + + // F# "pyramid of doom" durumuyla karşılaştırmayacak şekilde + // içgüdüsel eşzamansız özelliklere sahiptir. + // + // Bir sonraki örnek bir web sayfasını paralel bir şekilde indirir. + + open System.Net + open System + open System.IO + open Microsoft.FSharp.Control.CommonExtensions + + // İçeriği eşzamansız bir şekilde getir + let eşzamansızUrlGetir url = + async { // "async" anahtar kelimesi ve kıvrık parantez + // "async (eşzamansız)" nesneyi oluşturur + let istek = WebRequest.Create(Uri(url)) + use! cevap = istek.AsyncGetResponse() + // use! eşzamansız atamadır + use akış = cevap.GetResponseStream() + // "use" kullanılan bloğun dışına çıkınca + // close()'u otomatik olarak tetikler + use okuyucu = new IO.StreamReader(akış) + let html = okuyucu.ReadToEnd() + printfn "İndirme tamamlandı: %s" url + } + + // İndirmek için bir web sitesi listesi + let siteler = ["http://www.bing.com"; + "http://www.google.com"; + "http://www.microsoft.com"; + "http://www.amazon.com"; + "http://www.yahoo.com"] + + // İndir + siteler + |> List.map eşzamansızUrlGetir // eşzamansız görevlerden oluşan bir liste yap + |> Async.Parallel // bu görevleri paralel çalışacak şekilde ayarla + |> Async.RunSynchronously // başlat + +// ================================================ +// .NET uyumluluğu +// ================================================ + +module NetUyumlulukÖrnekleri = + + // F#, C#'ın yapabildiği hemen herşeyi yapabilir, + // ve .NET ve Mono kütüphaneleriyle tereyağından kıl çeker gibi çalışır. + + // ------- var olan kütüphane fonksiyonları ile çalışma ------- + + let (i1başarılı, i1) = System.Int32.TryParse("123"); + if i1başarılı then printfn "%i olarak dönüştürüldü" i1 else printfn "dönüştürme başarısız" + + // ------- Arayüzleri yol üstünde tanımlayın! ------- + + // IDisposable'ı sağlayan yeni bir nesne oluştur + let kaynakOluştur isim = + { new System.IDisposable + with member this.Dispose() = printfn "%s atıldı" isim } + + let kaynakKullanVeAt = + use r1 = kaynakOluştur "birinci kaynak" + printfn "birinci kaynağı kullanıyor" + for i in [1..3] do + let kaynakİsmi = sprintf "\tiç kaynak %d" i + use geçici = kaynakOluştur kaynakİsmi + printfn "\t%s ile bir şey yap" kaynakİsmi + use r2 = kaynakOluştur "ikinci kaynak" + printfn "ikinci kaynağı kullanıyor" + printfn "bitti." + + // ------- Nesne yönelimli kod ------- + + // F# aynı zamanda tam bir nesne yönelimli dildir. + // Sınıfları, kalıtımı ve sanal metotları destekler. + + // Genel tipli bir arayüz + type IEnumerator<'a> = + abstract member Şimdiki : 'a + abstract SonrakineGeç : unit -> bool + + // Sanal metotları olan soyut temel sınıflar + [<AbstractClass>] + type Şekil() = + // sadece okunabilir özellikler + abstract member Genişlik : int with get + abstract member Yükseklik : int with get + // sanal olmayan metot + member this.ÇevreleyenAlan = this.Yükseklik * this.Genişlik + // temel uygulamasıyla bir sanal metot + abstract member Yazdır : unit -> unit + default this.Yazdır () = printfn "Ben bir şekil (önümden çekil!)" + + // Somut bir sınıfın soyut sınıftan kalıtımı + type Dikdörtgen(x:int, y:int) = + inherit Şekil() + override this.Genişlik = x + override this.Yükseklik = y + override this.Yazdır () = printfn "Ben bir dikdörtgenim" + + // test + let r = Dikdörtgen(2, 3) + printfn "Genişlik: %i" r.Genişlik + printfn "Çevreleyen Alan: %i" r.ÇevreleyenAlan + r.Yazdır() + + // ------- ekleme metotları ------- + + // C#'ta olduğu gibi F# da var olan sınıfları ekleme metotları ile genişletebilir. + type System.String with + member this.StartsWithA = this.StartsWith "A" + + // test + let s = "Ahmet" + printfn "'%s' 'A' ile başlar = %A" s s.StartsWithA + + // ------- olaylar ------- + + type Butonum() = + let tıklamaOlayı = new Event<_>() + + [<CLIEvent>] + member this.OnClick = tıklamaOlayı.Publish + + member this.DenemeOlayı(arg) = + tıklamaOlayı.Trigger(this, arg) + + // test + let butonum = new Butonum() + butonum.OnClick.Add(fun (sender, arg) -> + printfn "arg=%O ile beraber bir tıklama olayı" arg) + + butonum.DenemeOlayı("Merhaba Dünya!") + +``` + +## Daha fazla bilgi + +F# hakkında daha fazla demo için [Try F#](http://www.tryfsharp.org/Learn) sitesine gidin, veya benim (yazarın) [why use F#](http://fsharpforfunandprofit.com/why-use-fsharp/) serimi okuyun. + +F# hakkında daha fazla bilgi için: [fsharp.org](http://fsharp.org/). |