haskell类型基础

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)

自定义类型.png

data是关键字,=号左边是类型构造,可以带参数定义泛形类型。=号右边是数据构造,用于构造类型实例,多个数据构造用|分割。类型构造和数据构造的名称不要求相同。

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

你可能感兴趣的:(haskell类型基础)