data Shape = Circle Point Float | Rectangle Point Point deriving (Show)
派生自Show, 就可show值成字符串
data Person = Person {firstName :: String , lastName :: String } deriving (Show) # Record Syntax, 同 Person String String, 但自动生成同名的取值函数,show显示也改变 let p = Person {firstName="aa", lastName="bb"} tellPerson :: Person -> String tellPerson (Person {firstName = a, lastName = b}) = a ++ b
data Maybe a = Nothing | Just adata Car a b = Car { company :: a , year :: b } deriving (Show)tellCar :: (Show a) => Car String a -> String
类型别名
type String = [Char]
type AssocList k v = [(k,v)]
别名类型构造子
type IntMap = Map Int
不全调用得到不全类型构造子, 同 type intMap v = Map Int v
infixr
infixr 5 :-:
定义中缀构造子, 5是优先级, :-:是符号
默认left-associative
infixr 5 .++(.++) :: List a -> List a -> List aEmpty .++ ys = ys(x :-: xs) .++ ys = x :-: (xs .++ ys)
recursive data structures
data List a = Empty | a :-: (List a) deriving (Show, Read, Eq, Ord)
typeclass
class Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool x == y = not (x /= y) x /= y = not (x == y) # 只需要instance一个定义就好,这个定义叫minimal complete definitiondata TrafficLight = Red | Yellow | Greeninstance Eq TrafficLight where Red == Red = True Green == Green = True Yellow == Yellow = True _ == _ = Falseinstance Show TrafficLight where show Red = "Red light" show Yellow = "Yellow light" show Green = "Green light"class (Eq a) => Num a where # Num 是 Eq 的 subclass, 要是Num必是Eqinstance (Eq m) => Eq (Maybe m) where Just x == Just y = x == y Nothing == Nothing = True _ == _ = False
o→ Either
data Either a b = Left a | Right a deriving (Eq, Ord, Read, Show)
o→ Tree
data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)
o→ YesNo
class YesNo a where yesno :: a -> Boolinstance YesNo Int where yesno 0 = False yesno _ = True
o→ Functor
class Functor f where # map over fmap :: (a -> b) -> f a -> f binstance Functor Maybe where # 接收构造子而非类型 fmap f (Just x) = Just (f x) fmap f Nothing = Nothinginstance Functor (Either a) where # parital apply Either, Either a 是个类型构造子 fmap f (Right x) = Right (f x) fmap f (Left x) = Left xinstance Functor ((->) r) where # 对函数的functor fmap f g = (\x -> f (g x))
boomBangs xs = [if x < 10 then "BOOM!" else "BANG!" | x <-xs, odd x][x*y | x <-[1,2], y <-[3,4]] # 聚合得[3,4,6,8]length' xs = sum [1 | _ <- xs]xxs = [[1,2], [3,4]][[x | x <- xs, even x] | xs <- xxs][(a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 = c ^2][a + b | (a,b) <- xs] # list comprehension中的模式匹配
模式匹配
x:xs
x:y:z:xs
函数
函数名与参数,参数与参数之间有空格隔开
函数比运算符先结合
let area r = pi * r ^ 2
定义函数
area 2
area (-2)
let area2 r = area r
let first (x, y) = x
接收元组
uppercase, lowercase :: String -> String
指定函数类型
分段定义
编译成case语句
f 0 = 1
f 1 = 5
f _ = -1
函数合成调用
square (f 1)
(square . f) 1
(\xs → length xs > 15)
lambda表达式
lambda可以用模式匹配,但使用不了多个模式
I/O action
在main中 I/O action才被执行
return () 语句产生I/O action, do接着执行
执行后会打印结果,结果为()时不打印
main = do _ <- putStrLn "a" name <- getLine putStrLn (name)
monad
o→ do
doGuessing num = do putStrLn "Enter your guess:" guess <- getLine if (read guess) < num then do putStrLn "Too low" doGuessing num else if (read guess) > num then do putStrLn "Too high" doGuessing num else putStrLn "You Win" # 只有一个动作时,可省略do
o→ do
doGuessing num = do putStrLn "Enter your guess:" guess <- getLine case compare (read guess) num of LT -> do putStrLn "Too low" GT -> do putStrLn "Too high" EQ -> putStrLn "You Win"
o→ functor applicative monad
class Functor f wherefmap :: (a -> b) -> f a -> f bclass Functor f => Applicative f wherepure :: a -> f a() :: f (a -> b) -> f a -> f bclass Applicative m => Monad m wherereturn :: a -> m a(>>=) :: m a -> (a -> m b) -> m b(>>) :: m a -> m b -> m bx >> y = x >>= \_ -> yfail :: String -> m afail msg = error msginstance Functor Maybe wherefmap func (Just x) = Just (func x)fmap func Nothing = Nothinginstance Applicative Maybe wherepure = JustNothing _ = Nothing(Just func) something = fmap func somethinginstance Monad Maybe wherereturn = JustNothing >>= func = NothingJust x >>= func = func x