2014-10-31 89 views
9

我瞭解到,type同義詞是現有類型的新名稱。它可以使用像這是什麼意思?使用'type'

type MyChar = Char 

但這是什麼意思?

class HasField a where 
    type FieldType a :: * 

回答

11

這是一個associated type family,如果你使用的編譯

{-# LANGUAGE TypeFamilies #-} 

或參數-XTypeFamilies傳遞給GHCGHCI由GHC提供的擴展。

基本上,它聲明瞭一個類,使得類的每個實例都可以單獨定義類型同義詞的含義。例如:

data MyDataType = MyDataConstructor Int 

instance HasField MyDataType where 
    type FieldType MyDataType = Int 
+0

我現在看到,謝謝!我想也許最好在開始閱讀一些開源代碼之前通過GHC用戶指南...... – hl1020 2014-10-31 08:42:30

2

所有這一切都有點先進的,所以如果你剛開始接觸Haskell的不喜歡,你必須明白這一點的時候了。

這麼說,我將添加一個簡單的例子來與Orjan的回答,想象我們這樣定義一個類:

-- | Class for types that can be constructed from a list of items. 
class Unfoldable t where 
    fromList :: [a] -> t a 

現在,我們可以定義實例各種類型:

import Data.Set (Set) 
import qualified Data.Set as Set 

instance Unfoldable [] where 
    fromList = id 

instance Unfoldable Set where 
    fromList = Set.fromList 

但這有兩個缺點:

  • 它不適用於單形類型:沒有其元素類型參數的類型。例如,ByteStringText是單態 - 它們的元素類型分別硬編碼爲Char8Char
  • 這將是很高興有fromList :: Ord k = [(k, v)] -> Map k v, but that definition doesn't support it, because(k,v)is not a type parameter of地圖。

因此,使用TypeFamilies有可能改善它:

{-# LANGUAGE TypeFamilies, ConstraintKinds #-} 

import Data.Monoid 
import Data.Set (Set) 
import qualified Data.Set as Set 
import Data.Map (Map) 
import qualified Data.Map as Map 
import Data.Text (Text, pack) 
import GHC.Exts (Constraint) 

class Monoid m => Unfoldable m where 
    type Element m :: * 
    type Constraint m :: GHC.Exts.Constraint 
    type Constraint m =() 

    fromList :: [Element m] -> m 

instance Unfoldable [a] where 
    type Element [a] = a 
    fromList as = as 

instance Ord a => Unfoldable (Set a) where 
    type Element (Set a) = a 
    type Constraint (Set a) = Ord a 
    fromList = Set.fromList 

instance Ord k => Unfoldable (Map k v) where 
    type Element (Map k v) = (k, v) 
    type Constraint (Map k v) = Ord k 
    fromList = Map.fromList 

instance Unfoldable Text where 
    type Element Text = Char 
    fromList = pack 

看的fromList :: Monoid m => [Element m] -> m類型。基本上,Element m是同義詞,其擴張是的m每個differenct選擇不同:

  • Element [a] := a
  • Element (Map k v) := (k ,v)
  • Element Text := Char

這裏的其它特技是利用ConstraintKinds以允許每個類實例需要對類型變量進行個性化約束(例如,Ord kMap)。這是另一天的話題...

+0

(1)我看到你定義了'Constraint'類型,但是你似乎沒有使用它。我想你想把它作爲'fromList'的限制嗎? (2)如果你堅持使用衝突名稱'Constraint',我認爲'GHC.Exts'應該被導入'qualified',即使這種情況在定義實例時工作。 – 2014-11-01 04:26:52