In [1]:
-- 方法1 使用data定义类型
-- 左边为类型名, 右边有类型值构造器`
data Bool = False | True
In [2]:
-- 构造自己的类型
data Shape = Circle Float Float Float | Rectangle Float Float Float Float
In [3]:
:t Circle
In [4]:
:t Rectangle
In [5]:
-- 值构造器类似函数调用
In [7]:
-- 这里Shape是类型,而Shape/Circle不是
area :: Shape -> Float
area (Circle _ _ r) = pi * r ^ 2
area (Rectangle x1 y1 x2 y2) = (abs $ x2 - x1) * (abs $ y2 - y1)
In [9]:
area $ Circle 10 20 10
In [10]:
area $ Rectangle 0 0 100 100
In [11]:
-- 实现show类型类才能显示在终端,类似__str__方法
data Shape = Circle Float Float Float | Rectangle Float Float Float Float
deriving (Show)
In [12]:
Circle 10 20 5
In [13]:
Rectangle 50 230 60 90
In [14]:
-- 值构造器本质是函数,所以可以部分应用
map (Circle 10 20) [4..7]
In [17]:
-- point类型,类型组合
-- 值构造器可以和类型同名
data Point = Point Float Float deriving (Show)
data Shape = Circle Point Float | Rectangle Point Point deriving (Show)
In [18]:
area :: Shape -> Float
area (Circle _ r) = pi * r ^ 2
area (Rectangle (Point x1 y1) (Point x2 y2)) = (abs $ x2 - x1) * (abs $ y2 - y1)
In [19]:
area (Rectangle (Point 0 0) (Point 100 100))
In [20]:
area (Circle (Point 0 0) 24)
In [21]:
nudge :: Shape -> Float -> Float -> Shape
nudge (Circle (Point x y) r) a b = Circle (Point (x+a) (y+b)) r
nudge (Rectangle (Point x1 y1) (Point x2 y2)) a b = Rectangle (Point (x1+a) (y1+b)) (Point (x2 + a) (y2 + b))
In [23]:
nudge (Circle (Point 34 34) 10) 5 10
In [25]:
baseCircle :: Float -> Shape
baseCircle r = Circle (Point 0 0) r
In [26]:
baseRect :: Float -> Float -> Shape
baseRect width height = Rectangle (Point 0 0) (Point width height)
In [27]:
nudge (baseRect 40 100) 60 23
In [28]:
-- 模块中可以导出类型, 方便外部使用
-- module Shapes (Shape(..), Point(..), area, nudge) where
-- Shape(..)导出shape所有值构造器, 等价于Shape(Circle, Rectangle)
-- Shape会不导出值构造器.
-- 也可不导出,抽象度更高. 但无法使用类型匹配
In [30]:
-- 第二种数据类型创建方法
-- 非纪录语法
data Person = Person String String deriving (Show)
let guy = Person "Buddy" "Frink"
guy
In [31]:
firstName :: Person -> String
firstName (Person first _) = first
In [32]:
lastName :: Person -> String
lastName (Person _ lastname) = lastname
In [33]:
firstName guy
In [35]:
lastName guy
In [36]:
-- 记录语法, 可以直接通过字段取值,类型ruby extends
-- show更好看
data Person = Person {firstName :: String
, lastName :: String
, age :: Int } deriving (Show)
In [37]:
:t age
In [38]:
data Car = Car String String Int deriving (Show)
In [39]:
:t Car
In [40]:
Car "Ford" "Must" 1978
In [44]:
-- XXX errors
data Car = Car { company :: String
, model :: String
, year :: Int } deriving (Show)
In [45]:
:t Car
In [47]:
-- 类型参数, 类型可以取参数产生新类型
-- Maybe变为类型构造器,
data Maybe a = Nothing | Just a
In [48]:
Just 3 :: Maybe Int
In [49]:
-- 列表是类型参数
In [50]:
Just "Haha"
In [51]:
-- 配合记录语法
data Car = Car { company :: a
, model :: b
, year :: c } deriving (Show)
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]: