前面我們說過了Type和typeclasses,現在,我們來說一說怎麼自定義自己的Type和TypeClasses,這東西我們覺得不好理解,其實簡單的說,你就把他們看成C語言中的結構體就行了,我們在C語言中自定義結構體實際上就是自定義新的數據類型。
一般的Types自定義
正如C語言中使用typedef struct XXX
來自定義結構體,在Haskell中
-
使用
data
來自定義Types,比如,我們需要定義一個圓,它由圓心座標和半價組成,我們可以這樣定義:data Circle = Circle Float Float Float
前面兩個Float表示圓心座標,後面一個表示半徑。
-
deriving (Show)
加在聲明的後面,那 Haskell 就會自動將該類型至於 Show 類型類之中
Record Syntax
我們按照上面的方式自定義一個Person的結構
data Person = Person String String Int Float String String deriving (Show)
如果我們需要獲取這個Person的各個子項的話,我們需要寫如下函數:
firstName :: Person -> String
firstName (Person firstname _ _ _ _ _) = firstname
lastName :: Person -> String
lastName (Person _ lastname _ _ _ _) = lastname
age :: Person -> Int
age (Person _ _ age _ _ _) = age
height :: Person -> Float
height (Person _ _ _ height _ _) = height
phoneNumber :: Person -> String
phoneNumber (Person _ _ _ _ number _) = number
flavor :: Person -> String
flavor (Person _ _ _ _ _ flavor) = flavor
如果定義一個非常複雜的數據結構,那獲取子項的函數將非常麻煩,有沒有簡單一點的方式呢?當然有啦。這就是Record Syntax
,記錄語法吧,暫且這麼翻譯。
使用Record Syntax
的聲明如下:
data Person = Person { firstName :: String
, lastName :: String
, age :: Int
, height :: Float
, phoneNumber :: String
, flavor :: String
} deriving (Show)
- 與原先讓那些項一個挨一個的空格隔開不同,這裏用了花括號
{}
- 先寫出項的名字,如
firstName
,後跟兩個冒號::
- 標明其類型,返回的數據類型仍與以前相同
- 各項之間用
,
隔開 - 這樣,就由系統自動生成了上述獲取各個值的get函數了。
同樣,使用的時候也要這麼來做:
Person {firstName="Ford", lastName="Mustang", age=30,height=60.0,phoneNumber="1234567",flavor="abc"}