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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容