Haskell Notları – 3 (Listeler)

Haskell’in en güzel yönlerinden birisi olan listelere bakacağız şimdi.

Listeler

Prelude> [1,2,3,4]
[1,2,3,4]
Prelude> ["eleman", "eleman 2"]
["eleman","eleman 2"]
Prelude> [True, True, False, True]
[True,True,False,True]

Aklınıza gelebilecek her şeyi bir listenin içine koyabiliyoruz. Burada dikkat edilmesi gereken nokta, listenin bütün elemanlarının aynı türden olması gereklilliği. Yani şöyle bir şey hata verecektir:

Prelude> [1,"iki",3]

<interactive>:6:2: error:
    • No instance for (Num [Char]) arising from the literal ‘1’
...

Birden fazla boyutlu listeler de oluşturabiliriz. Yine aynı şekilde, alt-listeler yine aynı türden elemanları içermeli, fakat içerdiği eleman sayısı değişebilir.

Prelude> [[1,2,3], [4,5], [22]]
[[1,2,3],[4,5],[22]]
Prelude> [[], ["deneme"]]
[[],["deneme"]]

Liste Oluşturma

Yukarıda kullandığımız liste notasyonu, örneğin [1,2,3,4], aslında 1:2:3:4:[] gösteriminin bir sözdizimsel şekeri (syntactic sugar). Bu gösterimi incelemekte yarar var, çünkü ilerde oldukça işimizi kolaylaştıracak.

: operatörü, cons olarak okunuyor ve yaptığı şey elemanları alıp tek tek bir listeye sevk etmek. Elimizde bir liste var ve başına eleman eklemek istiyorsak şöyle bir şey işimizi görecektir:

Prelude> 1:[2,3,4]
[1,2,3,4]

Birden fazla elemanı da bu şekilde ekleyebilirim:

Prelude> 1:2:3:[4,5,6,7]
[1,2,3,4,5,6,7]

Hatta elimde, listelerden oluşan bir liste varsa, yine bu notasyon ile listenin başına ekleme yapabilirim:

Prelude> [1,2,3]:[[4,5,6], [7,8,9]]
[[1,2,3],[4,5,6],[7,8,9]]

Bir önceki yazıdan hazırlayacağınız ++ operatörü ile de aynı işlemi yapabilirim aslında:

Prelude> [[1,2,3]] ++ [[4,5,6], [7,8,9]]
[[1,2,3],[4,5,6],[7,8,9]]

Fark ettiyseniz, ++ operatörü iki tane aynı türden listeyi alıp birleştiriyor. : ise gelen elemanları bir listenin başına ekliyor. Böyle durumlarda elinizden geldiğince : operatörünü tercih edin, çünkü bu operatör sabit bir zamanda çalışıyor fakat ++ O(n) karmaşıklığına sahip.

Durumu özetleyecek olursak, notasyon şöyle:

eleman:eleman:...:eleman:liste
liste ++ liste

Kullanım örnekleri:

Prelude> 'h':'a':'s':'k':'e':'l':'l':[]
"haskell"
Prelude> 'h':'a':"skell"
"haskell"
Prelude> "has" ++ "kell"
"haskell"
Prelude> 'h':'a':'s':'k':'e':'l':'l':[] == "haskell"
True

Karakterleri belirtirken ' kullanırken String‘ler için " kullanıyoruz, gözden kaçırılmaması gereken bir nokta da bu. Dolayısıyla "h":"a":"s":[] gibi bir ifade "has" değil, ["h","a","s"] gibi bir listeye dönüşecektir. Çünkü " işaretini kullandığımız için derleyici her bir harfi String olarak görüyor dolayısıyla bunları bir String listesine([String] diğer bir deyişle [[Char]]) dönüştürüyor.
Bir diğer dikkat edilmesi gereken nokta ise 1:2:3 gibi bir gösterimin hiçbir şey ifade etmemesi. Çünkü böyle bir konumda : operatörü için gereken listeyi sağlamamış oluyoruz. Fakat 1:2:3:[] ise tamamen doğru bir şekilde [1,2,3] listesini oluşturan bir ifade.

Temel liste fonksiyonları

Haskell’de bir listeyi şu şekilde görmek mümkün:

head    tail
|-||----------|
[1, 2, 3, 4, 5]
|----------||-|
    init    last

Bu çizimde anlatmaya çalıştığım şey, headin listenin ilk elemanını, lastın listenin son elemanını, initin listenin son elemanı hariç bütün elemanlarını, tailin ise listenin ilk elemanı hariç bütün elemanlarını ifade ettiği. Aynı zamanda bunlar bir fonksiyon olduğu için şöyle kullanabilirsiniz:

Prelude> head [5,4,3,2,1]  
5

Prelude> tail [5,4,3,2,1]  
[4,3,2,1]   

Prelude> last [5,4,3,2,1]  
1

Prelude> init [5,4,3,2,1]  
[5,4,3,2]

Haskell’in belkemiği olan recursive(özyinelemeli) fonksiyonlar için oldukça kullanışlı fonksiyonlar olacaklar. İleriki yazılarda nu fonksiyonların kullanımı da değineceğim. Burada bu yazıyı da kısa kesip, bir sonrakinde list comprehension kavramından bahsetmeye çalışacağım.

Leave a Reply