2016-02-13 32 views
1

GHC/Type families網頁上,它有一半關於類型系列有用的初始示例。如何編寫這個GHC類型系列示例的相關函數?

​​

基本上,它說一個Char列表可以用cons單元表示。 ()的列表除了長度以外沒有任何有用的信息,所以我們可以按其長度來表示列表。

太棒了。那麼這個列表的其他執行情況如何?如何定義length,以及如何定義!!fromList

回答

1

對於XList Char則可能是:

{-# LANGUAGE TypeFamilies #-} 
import Prelude hiding ((!!), length) 
import qualified Prelude 

class XList' a where 
    data family XList a :: * 
    fromList :: [a] -> XList a 
    length :: XList a -> Int 
    (!!)  :: XList a -> Int -> a 

instance XList' Char where 
    data XList Char = XCons !Char !(XList Char) | XNil 

    fromList []  = XNil 
    fromList (x:xs) = XCons x (fromList xs) 

    length XNil   = 0 
    length (XCons x xs) = 1 + length xs 

    XNil   !! _ = error "index error!" 
    (XCons x xs) !! 0 = x 
    (XCons x xs) !! k = xs !! (k - 1) 

則:

\> let a = fromList "wxyz" 
\> :t a 
a :: XList Char 
\> length a 
4 
\> a !! 2 
'y' 

同樣爲XList()

instance XList'() where 
    data XList() = XListUnit !Int 

    fromList a = XListUnit $ Prelude.length a 
    length (XListUnit n) = n 

    (XListUnit n) !! k 
     | k < 0 || n <= k = error "index error!" 
     | otherwise  =() 
+0

謝謝。網頁以獨立版本啓動,而不是與類型類關聯。你能否說明獨立版本是如何定義的? – Ana

+0

「關聯」類型和數據族差別很小。除了編譯器會在您實現類而不是系列(也可以具有關聯類型和數據族的默認值)時向您發出警告外,它們並非真正「關聯」。如果將'XList'移出類,這裏唯一的區別是語法:'數據XList ..其中...'成爲'數據實例XList ...其中...'並且它被移出實例聲明之外。 – user2407038

0

只是小編:

你可以將XList a保留爲非類型類型關聯類型族,並且只爲類型持有操作的類型XList添加類型類型;例如:

{-# LANGUAGE TypeFamilies #-} 

-- Original definition from your question 
data family XList a 
data instance XList Char = XCons !Char !(XList Char) | XNil 
data instance XList() = XListUnit !Int 

-- New class for XList-y types 
class XListy a where 
    length :: XList a -> Int 
    (!!) :: XList a -> Int -> a 
    fromList :: [a] -> XList a 

instance XListy() where 
    length (XListUnit n) = n 
    _ !! _ =() 
    fromList xs = XListUnit $ Prelude.length xs 
相關問題