Skip to content

AHABHGK

Haskell

纯函数式

惰性处理

强类型静态类型

不会产生副作用,可以返回一个副作用并被延迟执行

安装使用 stack,然后换成清华源,IDE 用 VSCode + HIE

10.1 + 0.2
2-- 0.30000000000000004
34 * (2.0 + 1)
4-- 12
5"hello" ++ " world"
6-- "hello world"
7['a', 'b']
8-- "ab"
9if 5 == 5 then "true" else "false"
10-- "true"
11if (1) then "true" else "false"
12-- error 强类型
13"one" + 1
14-- error
15
16:set +t -- 打开 t 查看类型
174
18-- 4
19-- it :: Num p => p
20:t 4 -- :t 查看类型
21-- it :: Num p => p

函数

1module Throwaway where
2
3double x = x * 2 -- 自动类型推断 double :: Num a => a -> a
4-- a 是一个类型变量,通过传入参数推断出类型 a,之后返回也是 a 类型
1module Throwaway where
2
3double :: Integer -> Integer
4double x = x * 2 -- double 2.0 -- error

递归

1let fact x = if x == 0 then 1 else fact (x - 1) * x -- fact :: (Eq p, Num p) => p -> p

模式匹配

1factorial :: Integer -> Integer
2factorial 0 = 1
3factorial x = x * factorial (x - 1)

哨兵表达式

1factorial :: Integer -> Integer
2factorial x
3 | x > 1 = x * factorial (x - 1)
4 | otherwise = 1

元组

1fibTuple :: (Integer, Integer, Integer) -> (Integer, Integer, Integer)
2fibTuple (x, y, 0) = (x, y, 0)
3fibTuple (x, y, index) = fibTuple (y, x + y, index - 1)
4
5fibResult :: (Integer, Integer, Integer) -> Integer
6fibResult (x, y, z) = x
7
8fib :: Integer -> Integer
9fib x = fibResult (fibTuple (0, 1, x))

元组和组合

1let second list = head (tail list) -- let 是局部定义
2let second = head . tail -- compose 简写
1fibNextPair :: (Integer, Integer) -> (Integer, Integer)
2fibNextPair (x, y) = (y, x + y)
3
4fibNthPair :: Integer -> (Integer, Integer)
5fibNthPair 1 = (1, 1)
6fibNthPair n = fibNextPair (fibNthPair (n - 1))
7
8fib :: Integer -> Integer
9fib = fst . fibNthPair -- fib n = fst (fibNthPair n)
1let h:t = [1, 2, 3, 4] -- h = 1, t = [2, 3, 4]
2
3size [] = 0
4size (h:t) = 1 + size t
5-- size "hello world" -> 11
6
7prod [] = 1
8prod (h:t) = h * prod t
9
10-- zip ['a', 'c'] ['b', 'd'] -> [('a', 'b'), ('c', 'd')]

生成列表

11:[2, 3] -- [1, 2, 3]
2[1]:[2, 3] -- error
3[1]:[[2], [3, 4]] -- [[1], [2], [3, 4]]
4
5allEven :: [Integer] -> [Integer]
6allEven [] = []
7allEven (h:t) = if even h then h:allEven t else allEven t
8-- allEven [1, 2, 3] -> [2]
1[1 .. 2] -- [1, 2]
2[1 .. 4] -- [1, 2, 3, 4]
3[10, 4] -- []
4[10, 9.5 .. 4] -- [10.0, 9.5, 9.0, 8.5, 8.0, 7.5, 7.0, 6.5, 6.0, 5.5, 5.0, 4.5, 4.0]
5
6take 5 [1 .. ] -- [1, 2, 3, 4, 5]
7take 5 [0, 3 .. ] -- [0, 3, 6, 9, 12]
1[x * 2 | x <- [1, 2, 3]] -- [2, 4, 6]
2[(y, x) | (x, y) <- [(1, 2), (2, 3)]] -- [(2, 1), (3, 2)]
3
4let crew = ["Lj", "Hgk"]
5[(a, b) | a <- crew, b <- crew, a /= b]
6-- [("Lj","Hgk"),("Hgk","Lj")]

高阶函数

1module Throwaway where
2 squareAll list = map square list
3 where square x = x * x
4-- squareAll [1, 2, 3] -> [1, 4, 9]
5
6map (\x -> x * x) [1, 2, 3]
7-- [1, 4, 9]
8
9map (+ 1) [1, 2, 3] -- (+ 1) 是偏函数
10-- [2, 3, 4]
11
12filter odd [1, 2, 3, 4, 5]
13-- [1, 3, 5]
14
15-- foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
16foldl (\cur acc -> acc + cur) 0 [1 .. 10] -- fold left
17-- 55
18
19-- foldl1 :: Foldable t => (a -> a -> a) -> t a -> a
20foldl1 (+) [1 .. 10]
21-- 55

柯里化

1let prod x y = x * y
2let double = prod 2
3let triple = prod 3

惰性求值

1myRange start step = start:(myRange (start + step) step)
2myRange 1 1 -- [1, 2, 3, ............]
3take 5 (myRange 10 2) -- [10, 12, 14, 16, 18]
1lazyFib x y = x:(lazyFib y (x + y))
2fib = lazyFib 1 1
3fibNth n = head (drop (n - 1) (take (n) fib))
4
5take 5 (lazyFib 1 1) -- [1, 1, 2, 3, 5]
6take 5 fib -- [1, 1, 2, 3, 5]
7take 5 (drop 200 fib) -- [453973694165307953197296969697410619233826, 734544867157818093234908902110449296423351, 1188518561323126046432205871807859915657177, 1923063428480944139667114773918309212080528, 3111581989804070186099320645726169127737705]
8fibNth 9 -- 34
9take 5 (zipWith (+) fib (drop 1 fib)) -- [2, 3, 5, 8, 13]
10take 5 (map (*2) [1 ..]) -- [2, 4, 6, 8, 10]
11take 5 (map ((* 2) . (* 5)) fib) -- [10, 10, 20, 30, 50]

类型

1'a' -- it :: Char
2"abc" -- it :: [Char]
3"abc" == ['a', 'b', 'c']
4-- True
5-- it :: Bool
PlayCard.hs
1module PlayCard where
2
3-- 自定义类型
4data Suit = Spades | Hearts deriving (Show) -- 继承 Show 函数
5data Rank = Ten | Jack | Queen | King | Ace deriving (Show)
6type Card = (Rank, Suit)
7type Hand = [Card]
8
9value :: Rank -> Integer
10value Ten = 1
11value Jack = 2
12value Queen = 3
13value King = 4
14value Ace = 5
15
16cardValue :: Card -> Integer
17cardValue (rank, suit) = value rank
1-- 范型
2backwards :: [a] -> [a] -- 不止是 Hand -> Hand
3backwards [] = []
4backwards (h:t) = backwards t ++ [h]
1data Triplet a = Trio a a a deriving (Show)
2:t Trio 'a' 'b' 'c' -- it :: Triplet Char
1-- 递归类型
2data Tree a = Children [Tree a] | Leaf a deriving (Show)
3depth (Leaf _) = 1
4depth (Children c) = 1 + maximum (map depth c)
5
6let tree = Children [Leaf 1, Children [Leaf 2, Leaf 3]]
7-- Children [Leaf 1, Children [Leaf 2, Leaf 3]]
8-- it :: Num a => Tree a
9
10-- 模式匹配
11let (Children ch) = tree
12-- ch -> [Leaf 1,Children [Leaf 2,Leaf 3]]
13
14depth tree -- 3
1class Eq a where
2 (==), (/=) :: a -> a -> Bool
3 -- 最小完整定义
4 -- (==) 或 (/=)
5 x /= y = not (x == y)
6 x == y = not (x /= y)
7
8-- hs 中 Eq 类的定义

🤩 monad

Haskell/Understanding monads

处理 I / O

1tryIo = do putStr "Enter your name: " ;
2 line <- getLine ;
3 let { backwards = reverse line } ;
4 return ("Hello. Your name backwards is " ++ backwards)

Maybe

1case (html doc) of
2 Nothing -> Nothing
3 Just x -> case body x of
4 Nothing -> Nothing
5 Just y -> paragraph 2 y

feeling

类型系统