1, haskell是静态类型语言,大部分情况依靠类型推断而不需要显示指定类型。
-- Int类型32bit或64bit,超过范围返回0
x :: Int
x= 2
-- Integer范围无限
y :: Integer
y= 2
letter :: Char
letter = 'a'
interestRate :: Double
interestRate = 0.375
isFun :: Bool
isFun = True
-- list类型元素必须是同一种类型
values :: [Int]
values = [1, 2, 3]
testScores :: [Double]
testScores = [0.99, 0.7, 0.8]
letters :: [Char]
letters = ['a', 'b', 'c']
-- String本质上就是[Char]类型
aPet :: [Char]
aPet = "cat"
anotherPet :: String
anotherPet = "dog"
-- tuple可以包含不同类型的元素
ageAndHeight ::(Int, Int)
ageAndHeight = (34, 74)
firstLastMiddle :: (String, String, Char)
firstLastMiddle = ("Oscar", "Grouch", 'D')
streetAddress :: (Int, String)
streetAddress = (123, "Happy St.")
-- 函数类型,haskell不支持自动类型转换
half :: Int -> Double
half n = (fromIntegral n) / 2
-- show把任意类型转成字符串
main :: IO ()
main = print $ show 6
-- read把字符串类型转为其他类型
number = read "6" :: Int
anotherNumber :: Int
anotherNumber = read "6"
-- 多参数函数,最后一个是返回值类型
makeAddress :: Int -> String -> String -> (Int, String, String)
makeAddress number street town = (number, street, town)
-- partial application
makeAddressLambda = (\number ->
(\street ->
(\town -> (number, street, town)))
-- 函数参数类型加小括号
ifEven :: (Int -> Int) -> Int -> Int
ifEven f n = if even n
then f n
else n
-- 类型声明中任何小写字符都可以表示任意类型(类似泛形)
simple :: a -> a
simple x = x
-- 相同字母表示同一种类型,不同字母可以表示同一种类型
makeTriple :: a -> b -> c -> (a, b, c)
makeTriple x y z = (x, y, z)
2, 自定义类型
2.1 type定义类型别名,相当于c++中的typedef/using
patientInfo :: String -> String -> Int -> Int -> String
patientInfo fname lname age height = name ++ " " ++ ageHeight
where name = lname ++ ", " ++ fname
ageHeight = "(" ++ show age ++ "yrs. " ++ show height ++ "in.)"
type FirstName = String
type LastName = String
type Age = Int
type Height = Int
patientInfo :: FirstName -> LastName -> Age -> Height -> String
2.2 data自定义类型(相当于c中的struct)
自定义类型.pngdata是关键字,=号左边是类型构造,可以带参数定义泛形类型。=号右边是数据构造,用于构造类型实例,多个数据构造用|分割。类型构造和数据构造的名称不要求相同。
type FirstName = String
type MiddleName = String
type LastName = String
-- 数据构造名称后面是参数类型
data Name = Name FirstName LastName
| NameWithMiddle FirstName MiddleName LastName
-- 模式匹配
showName :: Name -> String
showName (Name f l) = f ++ " " ++ l
showName (NameWithMiddle f m l) = f ++ " " ++ m ++ " " ++ l
name1 = Name "Jerome" "Salinger"
name2 = NameWithMiddle "Jerome" "David" "Salinger"
showName name1 = "Jerome Salinger"
showName name2 = "Jerome David Salinger"
-- record语法,用于字段较多的情况
data Patient = Patient { name :: Name
, sex :: Sex
, age :: Int
, height :: Int
, weight :: Int
, bloodType :: BloodType }
jackieSmith :: Patient
jackieSmith = Patient {name = Name "Jackie" "Smith"
, age = 43
, sex = Female
, height = 62
, weight = 115
, bloodType = BloodType O Neg }
-- getter:每个字段的类型都是:字段所在类型 -> 字段类型
height jackieSmith = 62
-- setter:返回一个新对象
jackieSmithUpdated = jackieSmith { age = 44 }
3,type classes(相当于java中的interface)
type classes.png-- 定义type classes
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
-- Ord继承Eq
class Eq a => Ord a where
compare :: a -> a -> Ordering
(<) :: a -> a -> Bool
(<=) :: a -> a -> Bool
(>) :: a -> a -> Bool
(>=) :: a -> a -> Bool
max :: a -> a -> a
min :: a -> a -> a
-- 调用type classes函数
min 1 2 = 2
-- type classes可以定义字段,相当于无参函数
class Bounded a where
minBound :: a
maxBound :: a
-- 访问type classes的字段需要指定实现类
minBound :: Int = -9223372036854775808
-- 自动实现内置的type classed(相当于java中从Object继承equals和toString)
data Icecream = Chocolate | Vanilla deriving (Show, Eq, Ord)
-- type classes多继承???
-- type classes函数默认实现???
type实现type classed
class Show a where
show :: a -> String
data SixSidedDie = S1 | S2 | S3 | S4 | S5 | S6
instance Show SixSidedDie where
show S1 = "one"
show S2 = "two"
show S3 = "three"
show S4 = "four"
show S5 = "five"
show S6 = "six"
多态:
read.png核心type classes层次结构
type classes层次结构.png
网友评论