2014-04-02 84 views
12

我在unm-hip包中找到了這段代碼。 So Pixel是一個功能?星星在這個haskell代碼中意味着什麼?

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)]] 

回答

15

作爲標準Haskell的擴展,您可以處理「種類」。種類對於類型和類型構造函數來說是一種非常基本的類型系統。種類*是一個簡單的類型,如Int。種類* -> *是一個類型構造函數,它接受一個類型並生成一個類型,如Maybe:將它傳遞給一個類型,如Int作爲參數,並且您得到類型Maybe Int

此代碼中使用的另一個擴展(我沒有注意到,因爲縮進丟失了)是關聯類型。標準Haskell中的類型類可以指定類型必須支持的多個函數。使用關聯的類型,它可以額外指定與該類型關聯的類型和類型構造函數。

在此,這意味着一個類型i那就是Imageable一個實例(即行爲像的圖像)必須具有相關聯的像素類型Pixel i,這必須是簡單類型(種類*),而不是一個類型構造函數。

+0

你知道爲什麼代碼作者使用這種設計嗎? – osager

+2

沒有太多的選擇。你有某種代表圖像的類型,而typeclass需要處理圖像中單個像素的函數。你需要一些方法來找出那個像素的類型。你可以修復它,但這不是很靈活。您可以使Imageable成爲圖像及其像素上的多參數類型類型,但是您需要函數依賴或類型歧義會使您發瘋,並且您仍然需要在使用該類的每個簽名中提及像素類型。相關的類型更清潔,更容易。 –

1

「So Pixel是一種功能?」

像素是一個類型級別的函數。它需要一個類型(它必須是一個Imageable的實例)並返回一種類型'*'。根據示例代碼中的用法,輸入類型也必須是「*」類型。因此,Pixel非常像Maybe,它們都是類型'* - > *'的「類型構造函數」,您爲它們提供了一個「簡單類型」,並返回一個「簡單類型」。它們在同一地點也有效。就像你不能有'Foo - > Maybe'類型的函數一樣,你也不能有'Bar - > Pixel'類型的函數。

+0

所以'type'關鍵字不像haskell Type Synonyms關鍵詞那麼正確?如果這是你說的爲什麼它不是這樣寫的:'type Pixel :: i - > *' – osager

+1

@osager它是相關的,但不一樣。當您提供(Imagable my_image)實例時,您的Pixel定義必須是現有類型,並且(Pixel my_image)將是該類型的別名/同義詞。這是一個稱爲(開放)類型的GHC擴展。 –

相關問題