第七章:型別類
型別類typeclass是Haskell中最出名的魔法之一。型別推斷系統System FC with roles。
型別類的實現包括型別宣告和例項宣告兩部分。
1.例項宣告 instance declaration
在第二章data時的例子中
data Position = Cartesian Double Double | Polar Double Double
Cartesian 3 4 == Polar 0.92729521 5
--?
因為資料型別Position不是Eq的一個例項,GHC拒絕編譯程式,我們需要使用例項宣告來解決這個問題
instance Eq Position where
Cartesian x1 y1 == Cartesian x2 y2 = (x1 == x2) && (y1 == y2)
Polar x1 y1 == Polar x2 y2 = (x1 == x2) && (y1 == y2)
Cartesian x y == Polar a r = (x == r * cos a) && (y == r * sin a)
Polar a r == Cartesian x y = (x == r * cos a) && (y == r * sin a)
Haskell 中有一長串Eq的例項:Bool, Char, Int, Word, () ... Prelude裡匯出的基本資料型別都是Eq的例項。
2.類宣告
類宣告使用的class語法
class ClassName typeVariable where
method1 :: type1
method2 :: type2
...
method1 = default1
method2 = default2
...
class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y = not (x == y)
x== y = not (x /= y )
3.型別類的實現
例項宣告和類宣告共同構成了Haskell 的型別類語法,我們把使用class宣告出來的型別叫做型別類。例如比較是否相等的Eq類,比較大小的Ord類,數值的Num類等。
Haskell中,型別類用了約定型別的行為,和型別對應的值沒有任何關係,只有當試圖使用Eq a限定型別a的時候,我們才真正用到了例項宣告中的函式。編譯器會自動幫助我們選擇符合型別類約束的型別實現型別類。
下圖展示了標準的Haskell類 Standard Haskell Classes From Haskell 2010 Language Report
- 層級和約束
上面的圖表中,有一條從Eq到Ord的線,代表Eq是Ord的父級型型別,意思是說,凡是可以比較大小的型別,都一定要能比較是否相等,這在Ord的型別宣告中被寫進了約束。
- 推導(derive)型別類
Haskell Report 中,規定這些型別類可以被推導: Eq, Ord, Enum, Bounded, Show和Read
- Show/Read
The Read and Show classes are used to convert values to or from strings. All Prelude types, except function types and IO types, are instances of Show and Read.
type ReadS a = String -> [(a,String)]
type ShowS = String -> String
class Read a where
readsPrec :: Int -> ReadS a
readList :: ReadS [a]
-- ... default decl for readList given in Prelude
class Show a where
showsPrec :: Int -> a -> ShowS
show :: a -> String
showList :: [a] -> ShowS
showsPrec _ x s = show x ++ s
show x = showsPrec 0 x ""
-- ... default decl for showList given in Prelude
相關文章
- 第七章-類基礎
- DM 類資料型別資料型別
- 原子更新基本型別類型別
- 型別轉換工具類型別
- PHP類方法的型別提示PHP型別
- 【Java】基本型別包裝類Java型別
- 原始型別與包裝類型別
- 泛型類、泛型方法、型別萬用字元的使用泛型型別字元
- 14.Java-Arrays(類)、基本型別包裝類、Integer(類)Java型別
- Java 包裝類和基本型別Java型別
- 理解類引用這種型別 (轉)型別
- JumpList中Recent類別和自定義型別薦型別
- 第11章 使用類——型別轉換(二)將自定義型別轉換為內建型別型別
- 二十八、基本型別包裝類型別
- 3.6 Java內部類四種型別Java型別
- 常見物件-基本型別包裝類物件型別
- C++隱式類型別轉換C++型別
- java基本資料型別包裝類Java資料型別
- C++ 隱式類型別轉換C++型別
- Scala由類的動態擴充套件想到型別類套件型別
- c++語言中類的私有型別或保護型別成員變數C++型別變數
- 在例項中呼叫 Invoke 型別的類型別
- MySQL 資料型別分類和選擇MySQL 資料型別
- JS資料型別分類和判斷JS資料型別
- 基本資料型別及其包裝類(一)資料型別
- 基本資料型別及其包裝類(二)資料型別
- Scala型別類的小應用之Functor Foldable型別LDA
- 字串與日期型別轉換的工具類字串型別
- 非型別的類别範本引數型別
- oracle10g_hint型別及分類Oracle型別
- C#學習 [型別系統] 類(13)C#型別
- scala_繼承、型別判斷、抽象類、匿名內部類繼承型別抽象
- 銷售和分銷憑證型別和專案類別型別
- Java中的基本型別包裝類 Integer 類該怎麼使用?Java型別
- 品類洞察 | 模擬經營品類有多少種玩法型別?型別
- 類例項物件的class型別卻不屬於該類,何解?物件型別
- 第10章 物件和類——物件和類(六) 抽象資料型別物件抽象資料型別
- 在 Kotlin 中“實現”trait/型別類KotlinAI型別