第31章:高階型別程式設計

夢飛發表於2017-03-20

由不同型別元素組成的列表——異類表的相關問題

1.Typeable和Dynamic

  • Data.Typeable模組 enter image description here

     --獲取型別資訊的方法
    typeOf :: forall a. Typeable a => a -> TypeRep
    
  • TypeRef

  • Proxy

    data Proxy a = Proxy
    

    enter image description here

  • Data.Dynamic模組

    data Dynamic = Dynamic TypeRep Obj
    toDyn :: Typeable a => a -> Dynamic
    fromDyn :: Typeable a => Dynamic -> a -> a    
    fromDynamic :: Typeable a => Dynamic -> Maybe a
    dynTypeRep :: Dynamic -> TypeRep
    

    但凡是Typeable型別類的資料,都可以和Dynamic相互轉換

  • GHC7.10後語言擴充套件AutoDeriveTypeable會自動開啟 -Typeable的存在,消除了任何隱式的基於型別的操作

2.存在型別 Existential Type

{-# LANGUAGE ExistentialQuantification #-}

data Dyn = forall a. Show a => Dyn a

instance Show Dyn where
    show (Dyn a) = "Dyn:" ++ Show a
  • 我們把上述在型別定義的右側,顯示地引入型別變數的型別叫做存在型別

  • 內聯型別類詞典

3.型別家族、資料家族和GADT

Haskell的型別系統一個強大的地方在於:可以把很多執行時才能解決的問題轉移到編譯階段。

  • 型別家族:type關鍵字在型別層面定義新的型別函式
  • 資料家族:data關鍵字可以定義新的型別以及對應的建構函式

    data family T a
    data    instance T Int  = T1 Int | T2 Bool
    newtype instance T Char = TC Bool
    
  • 在定義型別類的同時定義資料家族

    class GMapKey k where:
        data GMap k :: * -> *
        empty       :: GMap k v
        lookup      :: ...
    
  • GADT Generalised Algebraic Datatype

    data T ... where
        C1 ... :: T ...
        C2 ... :: T ...
        ...
    

4.資料類別 DataKinds

  • 通過語言擴充套件,GHC支援我們把data/newtype定義的資料型別提升成類別
  • Haskell自帶的資料型別和建構函式也可以提升成類別和對應的型別

    {-# LANGUAGE DataKinds, GADTs, kindsgnatures, TypeOperators #-}
    data HList :: [*] -> * where
        HNil :: Hlist '[]
        HCons :: x -> HList xs -> HList (x ': xs)
    

相關文章