2014-04-02 30 views
12

Bu kodu unm-hip paketinde buldum. Yani Pixel bir işlev midir?Bu haskell kodunda yıldız ne anlama geliyor?

class Imageable i where 
    type Pixel i :: * 
    rows :: i -> Int 
    cols :: i -> Int 
    ref :: i -> Int -> Int -> (Pixel i) 
    makeImage :: Int -> Int -> PixelOp (Pixel i) -> i 
    pixelList :: i -> [Pixel i] 
    pixelList i = [ ref i r c | r <- [0..(rows i - 1)], c <- [0..(cols i - 1)]] 

cevap

15

Standart Haskell'in bir uzantısı olarak "türler" ile ilgilenebilirsiniz. Çeşitler, tür ve tip kurucular için çok temel bir tip sistemdir. Tür *, Int gibi basit bir türüdür. Tür * -> *, bir tür alır ve bir tür verir, Maybe gibi bir tür kurucu: bağımsız değişken olarak Int gibi bir tür geçirin ve Maybe Int türünü alırsınız.

Bu kodda kullanılan diğer uzantı (ilk önce, girinti kaybolduktan sonra fark etmediğim) ilişkili türlerdir. Standart Haskell'deki bir yazım türü, türün desteklemesi gereken bir dizi işlevi belirleyebilir. İlişkili tiplerle, ek olarak türle ilişkilendirilmiş tipler ve tip kurucular da belirtebilir. Burada

bu Imageable bir örneğini (yani bir görüntü gibi davranır) bir tip i ilişkili bir piksel türü Pixel i olması gerektiği anlamına gelir, ve bu basit bir tür (tür *), bir tip kurucu olmalıdır.

+0

Kod yazarının bu tasarımı neden kullandığını biliyor musunuz? – osager

+2

Çok fazla seçenek yok. Bir resmi temsil eden türde bir türünüz vardır ve yazım penceresinin görüntüdeki tek bir pikselle ilgilenen işlevlere ihtiyacı vardır. Bu pikselin ne olduğunu öğrenmek için bir yoluna ihtiyacınız var. Düzeltebilirsin, ama bu çok esnek değil. Imageable'i görüntü ve piksele göre çok paramlı bir yazım ölçüsü yapabilirdiniz, ancak sonra işlevsel bağımlılıklara ihtiyacınız var ya da tür belirsizlikler sizi delirtecek ve sınıfa kullanılan her imzadaki piksel türünden bahsedmeniz gerekiyor. İlişkili tipler daha temiz ve daha kolaydır. –

1

"Yani Pixel bir işlev midir?"

Piksel, tür düzey bir işlevdir. Tek bir tür alır (Görüntülenebilir bir örneği olmalıdır) ve bir tür '*' döndürür. Örnek koddaki kullanımlarına dayanarak, giriş tipi de '*' olmalıdır. Yani, Pixel belki de çok gibi Belki de her ikisi de "tip kurucu" türler. "* -> *", onlara "basit bir tip" sağlarsınız ve "basit bir tür" döndürürler. Aynı lokasyonlarda da geçerlidir. Tıpkı 'Foo -> Belki' türünde bir fonksiyona sahip olamayacağınız gibi, 'Bar -> Piksel' türünde bir fonksiyona sahip olamayacaksınız.

+0

Yani 'type' anahtar sözcüğü, haskell Type eş anlamlıları anahtar kelimesiyle aynı değil midir? Eğer dediğiniz gibi, neden böyle yazılmıyorsa: 'yazın Pixel :: i -> *' – osager

+1

@osager İlgili, ama aynı değil. Bir (Imagable my_image) örneği sağladığınızda, Pixel tanımınız mevcut bir tip olmalı ve (Pixel my_image) bu tür bir takma ad/eşanlamlı olacaktır. Bu (açık) tip aileler denilen bir GHC uzantısı. –